mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Basic support for symbolic forms (#7408)
This commit is contained in:
@@ -86,6 +86,16 @@ static auto OperandDependence(Context& context,
|
||||
context.bundles().GetAsTuple(bundle_id));
|
||||
}
|
||||
|
||||
static auto OperandDependence(Context& context, SemIR::SpecificId specific_id)
|
||||
-> SemIR::ConstantDependence {
|
||||
auto specific = context.specifics().Get(specific_id);
|
||||
auto result = SemIR::ConstantDependence::None;
|
||||
for (auto arg_id : context.inst_blocks().Get(specific.args_id)) {
|
||||
result = std::max(result, OperandDependence(context, arg_id));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename IdT>
|
||||
requires SemIR::Internal::IsIdKindType<IdT>
|
||||
static auto OperandDependence(Context& /*context*/, IdT /*id*/)
|
||||
@@ -273,7 +283,7 @@ auto Internal::EndPerformDelayedAction(Context& context,
|
||||
} else {
|
||||
// TODO: pattern insts can depend on non-pattern insts, so we'll probably
|
||||
// eventually need to support actions that produce both.
|
||||
CARBON_CHECK(!contents.empty());
|
||||
CARBON_CHECK(contents.empty());
|
||||
block_id = context.pattern_block_stack().Pop();
|
||||
context.inst_block_stack().PopAndDiscard();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ auto PerformAction(Context& context, SemIR::LocId loc_id,
|
||||
auto PerformAction(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::OutFormParamPatternAction action) -> SemIR::InstId;
|
||||
|
||||
// Performs a caller pattern match action. Defined in pattern_match.cpp.
|
||||
auto PerformAction(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::CallerPatternMatchAction action) -> SemIR::InstId;
|
||||
|
||||
// Performs a callee pattern match action. Defined in pattern_match.cpp.
|
||||
auto PerformAction(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::CalleePatternMatchAction action) -> SemIR::InstId;
|
||||
|
||||
@@ -2290,8 +2290,12 @@ auto FormExprAsForm(Context& context, SemIR::LocId loc_id,
|
||||
return Context::FormExpr::Error;
|
||||
}
|
||||
|
||||
auto type_id = GetTypeComponent(context, form_inst_id);
|
||||
auto type_inst_id = context.types().GetTypeInstId(type_id);
|
||||
auto type_inst_id = context.types().GetAsTypeInstId(AddInst(
|
||||
context, SemIR::LocIdAndInst::RuntimeVerified(
|
||||
context.sem_ir(), loc_id,
|
||||
SemIR::TypeComponentOf{.type_id = SemIR::TypeType::TypeId,
|
||||
.form_inst_id = form_inst_id})));
|
||||
auto type_id = context.types().GetTypeIdForTypeInstId(type_inst_id);
|
||||
return {.form_inst_id = form_inst_id,
|
||||
.type_component_inst_id = type_inst_id,
|
||||
.type_component_id = type_id};
|
||||
|
||||
@@ -444,6 +444,7 @@ static auto InventCompoundClangArg(Context& context, SemIR::FormInfo form,
|
||||
|
||||
switch (form.kind) {
|
||||
case SemIR::FormInfo::Primitive:
|
||||
case SemIR::FormInfo::Dependent:
|
||||
CARBON_FATAL("Not a compound form");
|
||||
|
||||
case SemIR::FormInfo::Tuple: {
|
||||
@@ -536,6 +537,13 @@ auto InventClangArg(Context& context, SemIR::InstId arg_id) -> clang::Expr* {
|
||||
std::reverse(worklist.begin() + initial_size, worklist.end());
|
||||
break;
|
||||
}
|
||||
case SemIR::FormInfo::Dependent: {
|
||||
context.TODO(
|
||||
arg_id,
|
||||
"Support passing form-dependent args to C++ functions.");
|
||||
pending_results.push_back(nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -300,6 +300,7 @@ static auto CanDestroyType(
|
||||
case SemIR::BoolType::Kind:
|
||||
case SemIR::FacetType::Kind:
|
||||
case SemIR::FloatType::Kind:
|
||||
case SemIR::FormType::Kind:
|
||||
case SemIR::IntLiteralType::Kind:
|
||||
case SemIR::IntType::Kind:
|
||||
case SemIR::PointerType::Kind:
|
||||
|
||||
@@ -131,6 +131,16 @@ auto EvalConstantInst(Context& /*context*/, SemIR::ValueBinding /*inst*/)
|
||||
return ConstantEvalResult::NotConstant;
|
||||
}
|
||||
|
||||
auto EvalConstantInst(Context& context, SemIR::WrapperBinding inst)
|
||||
-> ConstantEvalResult {
|
||||
// A wrapper binding evaluates to the value it's bound to.
|
||||
if (inst.value_id.has_value()) {
|
||||
return ConstantEvalResult::Existing(
|
||||
context.constant_values().Get(inst.value_id));
|
||||
}
|
||||
return ConstantEvalResult::NotConstant;
|
||||
}
|
||||
|
||||
auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
|
||||
SemIR::AcquireValue inst) -> ConstantEvalResult {
|
||||
SemIR::ConstantId const_id = SemIR::ConstantId::NotConstant;
|
||||
|
||||
@@ -384,7 +384,7 @@ auto CheckFunctionDefinitionSignature(Context& context,
|
||||
|
||||
// The parameter types need to be complete.
|
||||
RequireCompleteType(
|
||||
context, context.insts().GetAs<SemIR::AnyParam>(param_ref_id).type_id,
|
||||
context, context.insts().Get(param_ref_id).type_id(),
|
||||
SemIR::LocId(param_ref_id), [&](auto& builder) {
|
||||
CARBON_DIAGNOSTIC(
|
||||
IncompleteTypeInFunctionParam, Context,
|
||||
@@ -406,10 +406,9 @@ auto CheckFunctionDefinitionSignature(Context& context,
|
||||
if (return_call_param.has_value()) {
|
||||
// TODO: If the types are already checked for completeness then this does
|
||||
// nothing?
|
||||
TryToCompleteType(
|
||||
context,
|
||||
context.insts().GetAs<SemIR::AnyParam>(return_call_param).type_id,
|
||||
SemIR::LocId(return_call_param));
|
||||
TryToCompleteType(context,
|
||||
context.insts().Get(return_call_param).type_id(),
|
||||
SemIR::LocId(return_call_param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,11 +165,6 @@ static auto HandleAnyBindingPattern(
|
||||
SemIR::InstId self_type_inst_id = SemIR::InstId::None) -> bool {
|
||||
auto type_expr = HandleAnyBindingPatternType(context, node_id, node_kind,
|
||||
self_type_inst_id);
|
||||
if (context.types()
|
||||
.GetAsInst(type_expr.type_component_id)
|
||||
.Is<SemIR::TypeComponentOf>()) {
|
||||
return context.TODO(node_id, "Support symbolic form bindings");
|
||||
}
|
||||
|
||||
SemIR::ExprRegionId type_expr_region_id =
|
||||
ConsumeSubpatternExpr(context, type_expr.inst_id);
|
||||
|
||||
@@ -130,6 +130,9 @@ auto AddBindingForPattern(Context& context, SemIR::LocId name_loc,
|
||||
case SemIR::ValueParamPattern::Kind:
|
||||
bind_name_kind = SemIR::ValueBinding::Kind;
|
||||
break;
|
||||
case SemIR::SpliceInst::Kind:
|
||||
bind_name_kind = SemIR::WrapperBinding::Kind;
|
||||
break;
|
||||
default:
|
||||
CARBON_FATAL("Unexpected subpattern kind for at_binding_pattern: {0}",
|
||||
subpattern);
|
||||
|
||||
@@ -813,12 +813,29 @@ auto MatchContext::DoPostWork(State /*state*/,
|
||||
results_stack_.AppendToTop(tuple_value_id);
|
||||
}
|
||||
|
||||
auto MatchContext::DoPreWork(State state, SemIR::SpliceInst splice,
|
||||
auto MatchContext::DoPreWork(State state, SemIR::SpliceInst /*splice*/,
|
||||
SemIR::InstId scrutinee_id, WorkItem entry)
|
||||
-> void {
|
||||
auto specific_pattern_const_id = SemIR::GetConstantValueInSpecific(
|
||||
context_.sem_ir(), specific_id_stack_.back(), entry.pattern_id);
|
||||
auto specific_pattern_id =
|
||||
context_.constant_values().GetInstId(specific_pattern_const_id);
|
||||
CARBON_KIND_SWITCH(state) {
|
||||
case CARBON_KIND(CallerState* _): {
|
||||
CARBON_FATAL("TODO: support caller-side matching of pattern splices");
|
||||
case CARBON_KIND(CallerState* caller_state): {
|
||||
// TODO: find a way to defer adding the bundle until we know we're
|
||||
// adding the action.
|
||||
auto args_id = context_.bundles()
|
||||
.AddCanonical<SemIR::CallerPatternMatchAction::Args>(
|
||||
{.pattern_id = specific_pattern_id,
|
||||
.arg_id = scrutinee_id,
|
||||
.callee_specific_id = specific_id_stack_.back()});
|
||||
caller_state->call_args.push_back(
|
||||
HandleAction<SemIR::CallerPatternMatchAction>(
|
||||
context_, SemIR::LocId(entry.pattern_id),
|
||||
context_.types().GetTypeInstId(GetScrutineeTypeInSpecific(
|
||||
context_, entry.pattern_id, specific_id_stack_.back())),
|
||||
{.type_id = SemIR::InstType::TypeId, .args_id = args_id}));
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(ThunkState* _): {
|
||||
CARBON_FATAL("TODO: support thunk matching of pattern splices");
|
||||
@@ -830,12 +847,13 @@ auto MatchContext::DoPreWork(State state, SemIR::SpliceInst splice,
|
||||
CARBON_CHECK(!scrutinee_id.has_value());
|
||||
auto result_id = HandleAction<SemIR::CalleePatternMatchAction>(
|
||||
context_, SemIR::LocId(entry.pattern_id),
|
||||
context_.types().GetTypeInstId(splice.type_id),
|
||||
context_.types().GetTypeInstId(GetScrutineeTypeInSpecific(
|
||||
context_, entry.pattern_id, specific_id_stack_.back())),
|
||||
{.type_id = SemIR::InstType::TypeId,
|
||||
.args_id =
|
||||
context_.bundles()
|
||||
.AddCanonical<SemIR::CalleePatternMatchAction::Args>(
|
||||
{.pattern_id = entry.pattern_id,
|
||||
{.pattern_id = specific_pattern_id,
|
||||
.parent_index = callee_state->index.Allocate()})});
|
||||
callee_state->PushCallParamPattern(
|
||||
context_, SemIR::LocId(entry.pattern_id), entry.pattern_id,
|
||||
@@ -1097,6 +1115,22 @@ auto ThunkPatternMatch(Context& context,
|
||||
.ignored_call_args = state.outer_call_args};
|
||||
}
|
||||
|
||||
auto PerformAction(Context& context, SemIR::LocId /*loc_id*/,
|
||||
SemIR::CallerPatternMatchAction action) -> SemIR::InstId {
|
||||
auto args = context.bundles().Get(action.args_id);
|
||||
CallerState state;
|
||||
MatchContext match(context, args.callee_specific_id);
|
||||
|
||||
match.Match(&state,
|
||||
{.pattern_id = args.pattern_id,
|
||||
.work = MatchContext::PreWork{.scrutinee_id = args.arg_id},
|
||||
.allow_unmarked_ref = false});
|
||||
|
||||
CARBON_CHECK(state.call_args.size() == 1,
|
||||
"TODO: add support for composite forms");
|
||||
return state.call_args[0];
|
||||
}
|
||||
|
||||
auto PerformAction(Context& context, SemIR::LocId /*loc_id*/,
|
||||
SemIR::CalleePatternMatchAction action) -> SemIR::InstId {
|
||||
auto args = context.bundles().Get(action.args_id);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "toolchain/check/control_flow.h"
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/inst.h"
|
||||
#include "toolchain/sem_ir/expr_info.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
@@ -169,8 +170,8 @@ auto BuildReturnWithExpr(Context& context, SemIR::LocId loc_id,
|
||||
diag.Emit();
|
||||
expr_id = SemIR::ErrorInst::InstId;
|
||||
} else {
|
||||
auto return_form =
|
||||
context.insts().Get(function.GetDeclaredReturnForm(context.sem_ir()));
|
||||
auto return_form_id = function.GetDeclaredReturnForm(context.sem_ir());
|
||||
auto return_form = context.insts().Get(return_form_id);
|
||||
CARBON_KIND_SWITCH(return_form) {
|
||||
case CARBON_KIND(SemIR::InitForm _): {
|
||||
if (!SemIR::InitRepr::ForType(context.sem_ir(), return_type_id)
|
||||
@@ -210,6 +211,29 @@ auto BuildReturnWithExpr(Context& context, SemIR::LocId loc_id,
|
||||
expr_id = SemIR::ErrorInst::InstId;
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(SemIR::SymbolicBinding _): {
|
||||
auto expr_form_info = SemIR::GetFormInfo(context.sem_ir(), expr_id);
|
||||
if (expr_form_info.kind != SemIR::FormInfo::Dependent) {
|
||||
context.TODO(loc_id,
|
||||
"support nontrivial conversions between symbolic forms");
|
||||
expr_id = SemIR::ErrorInst::InstId;
|
||||
break;
|
||||
}
|
||||
auto expr_form_const_id = SemIR::GetConstantValueInSpecific(
|
||||
context.sem_ir(), SemIR::SpecificId::None,
|
||||
expr_form_info.form_inst_id);
|
||||
auto declared_form_const_id = SemIR::GetConstantValueInSpecific(
|
||||
context.sem_ir(), SemIR::SpecificId::None, return_form_id);
|
||||
if (expr_form_const_id != declared_form_const_id) {
|
||||
context.TODO(loc_id,
|
||||
"support nontrivial conversions between symbolic forms");
|
||||
expr_id = SemIR::ErrorInst::InstId;
|
||||
break;
|
||||
}
|
||||
// expr_id's form is identical to the expected form, so we can use it
|
||||
// directly.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CARBON_FATAL("Unexpected inst kind: {0}", return_form);
|
||||
}
|
||||
|
||||
+86
-84
@@ -31,20 +31,20 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: clang_decls: {}
|
||||
// CHECK:STDOUT: clang_decl_signatures: {}
|
||||
// CHECK:STDOUT: name_scopes:
|
||||
// CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Core): inst70000011, name0: inst7000002F}}
|
||||
// CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Core): inst70000011, name0: inst70000030}}
|
||||
// CHECK:STDOUT: name_scope70000001: {inst: inst70000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000016}}
|
||||
// CHECK:STDOUT: entity_names:
|
||||
// CHECK:STDOUT: entity_name70000000: {name: name(PeriodSelf), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
|
||||
// CHECK:STDOUT: entity_name70000001: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
|
||||
// CHECK:STDOUT: entity_name70000002: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0, form: inst<none>}
|
||||
// CHECK:STDOUT: functions:
|
||||
// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000020, return_form_inst_id: inst7000001F, return_pattern_id: inst70000028}
|
||||
// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000020, return_form_inst_id: inst7000001F, return_pattern_id: inst70000029}
|
||||
// CHECK:STDOUT: classes: {}
|
||||
// CHECK:STDOUT: interfaces: {}
|
||||
// CHECK:STDOUT: associated_constants: {}
|
||||
// CHECK:STDOUT: impls: {}
|
||||
// CHECK:STDOUT: generics:
|
||||
// CHECK:STDOUT: generic70000000: {decl: inst7000002F, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: generic70000000: {decl: inst70000030, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specifics:
|
||||
// CHECK:STDOUT: specific70000000: {generic: generic70000000, args: inst_block7000000C, decl_block_id: inst_block7000000E, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific_interfaces: {}
|
||||
@@ -76,13 +76,13 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: object_layout:
|
||||
// CHECK:STDOUT: size: 0
|
||||
// CHECK:STDOUT: alignment: 1
|
||||
// CHECK:STDOUT: 'type(inst70000034)':
|
||||
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000035)}
|
||||
// CHECK:STDOUT: 'type(inst70000035)':
|
||||
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000036)}
|
||||
// CHECK:STDOUT: object_layout:
|
||||
// CHECK:STDOUT: size: 0
|
||||
// CHECK:STDOUT: alignment: 1
|
||||
// CHECK:STDOUT: 'type(inst70000035)':
|
||||
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000035)}
|
||||
// CHECK:STDOUT: 'type(inst70000036)':
|
||||
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000036)}
|
||||
// CHECK:STDOUT: object_layout:
|
||||
// CHECK:STDOUT: size: 0
|
||||
// CHECK:STDOUT: alignment: 1
|
||||
@@ -106,32 +106,32 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: inst7000001D: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
|
||||
// CHECK:STDOUT: inst7000001E: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
|
||||
// CHECK:STDOUT: inst7000001F: {kind: NameRef, arg0: name1, arg1: inst7000001C, type: type(inst(FormType))}
|
||||
// CHECK:STDOUT: inst70000020: {kind: TypeComponentOf, arg0: inst7000001D, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000021: {kind: PatternType, arg0: inst70000020, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000022: {kind: OutFormParamPatternAction, arg0: inst7000001F, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000023: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst70000024: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst70000025: {kind: TypeComponentOf, arg0: inst7000001E, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000026: {kind: PatternType, arg0: inst70000025, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000027: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst70000028: {kind: ReturnSlotPattern, arg0: inst70000023, arg1: inst70000020, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst70000029: {kind: ReturnSlotPattern, arg0: inst70000024, arg1: inst70000020, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst7000002A: {kind: ReturnSlotPattern, arg0: inst70000027, arg1: inst70000025, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst7000002B: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000017, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst7000002C: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst7000002D: {kind: SpliceInst, arg0: inst7000002C, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst7000002E: {kind: ReturnSlot, arg0: inst70000020, arg1: inst7000002D, type: type(symbolic_constant70000009)}
|
||||
// CHECK:STDOUT: inst7000002F: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst70000034)}
|
||||
// CHECK:STDOUT: inst70000030: {kind: OutFormParamPatternAction, arg0: inst7000001D, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000031: {kind: SpliceInst, arg0: inst70000030, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst70000032: {kind: ReturnSlotPattern, arg0: inst70000031, arg1: inst70000020, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst70000033: {kind: CalleePatternMatchAction, arg0: bundle70000001, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000034: {kind: FunctionType, arg0: function70000000, arg1: specific<none>, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000035: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000036: {kind: StructValue, arg0: inst_block_empty, type: type(inst70000034)}
|
||||
// CHECK:STDOUT: inst70000020: {kind: TypeComponentOf, arg0: inst7000001F, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000021: {kind: TypeComponentOf, arg0: inst7000001D, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000022: {kind: TypeComponentOf, arg0: inst7000001E, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000023: {kind: PatternType, arg0: inst70000021, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000024: {kind: OutFormParamPatternAction, arg0: inst7000001F, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000025: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst70000026: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant70000007)}
|
||||
// CHECK:STDOUT: inst70000027: {kind: PatternType, arg0: inst70000022, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000028: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst70000029: {kind: ReturnSlotPattern, arg0: inst70000025, arg1: inst70000020, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst7000002A: {kind: ReturnSlotPattern, arg0: inst70000026, arg1: inst70000021, type: type(symbolic_constant70000007)}
|
||||
// CHECK:STDOUT: inst7000002B: {kind: ReturnSlotPattern, arg0: inst70000028, arg1: inst70000022, type: type(symbolic_constant7000000A)}
|
||||
// CHECK:STDOUT: inst7000002C: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000017, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst7000002D: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst7000002E: {kind: SpliceInst, arg0: inst7000002D, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst7000002F: {kind: ReturnSlot, arg0: inst70000021, arg1: inst7000002E, type: type(symbolic_constant70000006)}
|
||||
// CHECK:STDOUT: inst70000030: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst70000035)}
|
||||
// CHECK:STDOUT: inst70000031: {kind: OutFormParamPatternAction, arg0: inst7000001D, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000032: {kind: SpliceInst, arg0: inst70000031, type: type(symbolic_constant70000007)}
|
||||
// CHECK:STDOUT: inst70000033: {kind: ReturnSlotPattern, arg0: inst70000032, arg1: inst70000021, type: type(symbolic_constant70000007)}
|
||||
// CHECK:STDOUT: inst70000034: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
|
||||
// CHECK:STDOUT: inst70000035: {kind: FunctionType, arg0: function70000000, arg1: specific<none>, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000036: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
|
||||
// CHECK:STDOUT: inst70000037: {kind: StructValue, arg0: inst_block_empty, type: type(inst70000035)}
|
||||
// CHECK:STDOUT: bundles:
|
||||
// CHECK:STDOUT: bundle70000000: {arg0: inst70000023, arg1: call_param0}
|
||||
// CHECK:STDOUT: bundle70000001: {arg0: inst70000031, arg1: call_param0}
|
||||
// CHECK:STDOUT: bundle70000000: {arg0: inst70000026, arg1: call_param0}
|
||||
// CHECK:STDOUT: constant_values:
|
||||
// CHECK:STDOUT: values:
|
||||
// CHECK:STDOUT: instF: concrete_constant(instF)
|
||||
@@ -150,51 +150,52 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: inst7000001D: symbolic_constant70000003
|
||||
// CHECK:STDOUT: inst7000001E: symbolic_constant70000004
|
||||
// CHECK:STDOUT: inst7000001F: symbolic_constant70000004
|
||||
// CHECK:STDOUT: inst70000020: symbolic_constant70000005
|
||||
// CHECK:STDOUT: inst70000021: symbolic_constant70000006
|
||||
// CHECK:STDOUT: inst70000022: symbolic_constant70000007
|
||||
// CHECK:STDOUT: inst70000023: symbolic_constant7000000B
|
||||
// CHECK:STDOUT: inst70000020: symbolic_constant70000006
|
||||
// CHECK:STDOUT: inst70000021: symbolic_constant70000005
|
||||
// CHECK:STDOUT: inst70000022: symbolic_constant70000006
|
||||
// CHECK:STDOUT: inst70000023: symbolic_constant70000007
|
||||
// CHECK:STDOUT: inst70000024: symbolic_constant70000008
|
||||
// CHECK:STDOUT: inst70000025: symbolic_constant70000009
|
||||
// CHECK:STDOUT: inst70000026: symbolic_constant7000000A
|
||||
// CHECK:STDOUT: inst70000027: symbolic_constant7000000B
|
||||
// CHECK:STDOUT: inst70000028: symbolic_constant7000000D
|
||||
// CHECK:STDOUT: inst70000029: symbolic_constant7000000C
|
||||
// CHECK:STDOUT: inst7000002A: symbolic_constant7000000D
|
||||
// CHECK:STDOUT: inst7000002B: concrete_constant(inst(FormType))
|
||||
// CHECK:STDOUT: inst7000002C: symbolic_constant7000000E
|
||||
// CHECK:STDOUT: inst7000002F: concrete_constant(inst70000036)
|
||||
// CHECK:STDOUT: inst70000030: symbolic_constant7000000F
|
||||
// CHECK:STDOUT: inst70000031: symbolic_constant70000010
|
||||
// CHECK:STDOUT: inst70000032: symbolic_constant70000011
|
||||
// CHECK:STDOUT: inst70000033: symbolic_constant70000012
|
||||
// CHECK:STDOUT: inst70000034: concrete_constant(inst70000034)
|
||||
// CHECK:STDOUT: inst70000025: symbolic_constant7000000B
|
||||
// CHECK:STDOUT: inst70000026: symbolic_constant70000009
|
||||
// CHECK:STDOUT: inst70000027: symbolic_constant7000000A
|
||||
// CHECK:STDOUT: inst70000028: symbolic_constant7000000B
|
||||
// CHECK:STDOUT: inst70000029: symbolic_constant7000000D
|
||||
// CHECK:STDOUT: inst7000002A: symbolic_constant7000000C
|
||||
// CHECK:STDOUT: inst7000002B: symbolic_constant7000000D
|
||||
// CHECK:STDOUT: inst7000002C: concrete_constant(inst(FormType))
|
||||
// CHECK:STDOUT: inst7000002D: symbolic_constant7000000E
|
||||
// CHECK:STDOUT: inst70000030: concrete_constant(inst70000037)
|
||||
// CHECK:STDOUT: inst70000031: symbolic_constant7000000F
|
||||
// CHECK:STDOUT: inst70000032: symbolic_constant70000010
|
||||
// CHECK:STDOUT: inst70000033: symbolic_constant70000011
|
||||
// CHECK:STDOUT: inst70000034: symbolic_constant70000012
|
||||
// CHECK:STDOUT: inst70000035: concrete_constant(inst70000035)
|
||||
// CHECK:STDOUT: inst70000036: concrete_constant(inst70000036)
|
||||
// CHECK:STDOUT: inst70000037: concrete_constant(inst70000037)
|
||||
// CHECK:STDOUT: symbolic_constants:
|
||||
// CHECK:STDOUT: symbolic_constant70000000: {inst: inst70000014, kind: self, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000001: {inst: inst7000001A, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000002: {inst: inst7000001A, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl0}}
|
||||
// CHECK:STDOUT: symbolic_constant70000003: {inst: inst7000001D, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000004: {inst: inst7000001D, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl1}}
|
||||
// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000020, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000021, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000022, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl2}}
|
||||
// CHECK:STDOUT: symbolic_constant70000008: {inst: inst70000024, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000020, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl3}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000021, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl4}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000024, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst70000029, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst70000029, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst7000002C, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst70000030, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000010: {inst: inst70000031, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000032, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000033, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000021, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000021, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl2}}
|
||||
// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000023, kind: checked, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000008: {inst: inst70000024, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl3}}
|
||||
// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000026, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000023, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl4}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000026, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst7000002A, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst7000002A, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst7000002D, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}}
|
||||
// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst70000031, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000010: {inst: inst70000032, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000033, kind: template, attached: null}
|
||||
// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000034, kind: template, attached: null}
|
||||
// CHECK:STDOUT: inst_blocks:
|
||||
// CHECK:STDOUT: inst_block_empty: {}
|
||||
// CHECK:STDOUT: exports:
|
||||
// CHECK:STDOUT: 0: inst7000002F
|
||||
// CHECK:STDOUT: 0: inst70000030
|
||||
// CHECK:STDOUT: generated: {}
|
||||
// CHECK:STDOUT: imports:
|
||||
// CHECK:STDOUT: 0: inst70000011
|
||||
@@ -207,19 +208,20 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: inst_block70000006:
|
||||
// CHECK:STDOUT: 0: inst70000019
|
||||
// CHECK:STDOUT: inst_block70000007:
|
||||
// CHECK:STDOUT: 0: inst70000023
|
||||
// CHECK:STDOUT: 0: inst70000025
|
||||
// CHECK:STDOUT: inst_block70000008:
|
||||
// CHECK:STDOUT: 0: inst7000002D
|
||||
// CHECK:STDOUT: 0: inst7000002E
|
||||
// CHECK:STDOUT: inst_block70000009:
|
||||
// CHECK:STDOUT: 0: inst70000019
|
||||
// CHECK:STDOUT: 1: inst70000028
|
||||
// CHECK:STDOUT: 1: inst70000029
|
||||
// CHECK:STDOUT: inst_block7000000A:
|
||||
// CHECK:STDOUT: 0: inst7000001F
|
||||
// CHECK:STDOUT: 1: inst70000023
|
||||
// CHECK:STDOUT: 2: inst7000002B
|
||||
// CHECK:STDOUT: 3: inst7000001C
|
||||
// CHECK:STDOUT: 4: inst7000002D
|
||||
// CHECK:STDOUT: 1: inst70000020
|
||||
// CHECK:STDOUT: 2: inst70000025
|
||||
// CHECK:STDOUT: 3: inst7000002C
|
||||
// CHECK:STDOUT: 4: inst7000001C
|
||||
// CHECK:STDOUT: 5: inst7000002E
|
||||
// CHECK:STDOUT: 6: inst7000002F
|
||||
// CHECK:STDOUT: inst_block7000000B:
|
||||
// CHECK:STDOUT: 0: inst7000001C
|
||||
// CHECK:STDOUT: inst_block7000000C:
|
||||
@@ -228,24 +230,24 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: 0: inst7000001B
|
||||
// CHECK:STDOUT: 1: inst7000001E
|
||||
// CHECK:STDOUT: 2: inst70000022
|
||||
// CHECK:STDOUT: 3: inst70000025
|
||||
// CHECK:STDOUT: 4: inst70000026
|
||||
// CHECK:STDOUT: 5: inst70000027
|
||||
// CHECK:STDOUT: 6: inst7000002A
|
||||
// CHECK:STDOUT: 7: inst7000002C
|
||||
// CHECK:STDOUT: 3: inst70000024
|
||||
// CHECK:STDOUT: 4: inst70000027
|
||||
// CHECK:STDOUT: 5: inst70000028
|
||||
// CHECK:STDOUT: 6: inst7000002B
|
||||
// CHECK:STDOUT: 7: inst7000002D
|
||||
// CHECK:STDOUT: inst_block7000000E:
|
||||
// CHECK:STDOUT: 0: inst7000001A
|
||||
// CHECK:STDOUT: 1: inst7000001D
|
||||
// CHECK:STDOUT: 2: inst70000030
|
||||
// CHECK:STDOUT: 3: inst70000020
|
||||
// CHECK:STDOUT: 4: inst70000021
|
||||
// CHECK:STDOUT: 5: inst70000031
|
||||
// CHECK:STDOUT: 6: inst70000032
|
||||
// CHECK:STDOUT: 7: inst70000033
|
||||
// CHECK:STDOUT: 2: inst70000021
|
||||
// CHECK:STDOUT: 3: inst70000031
|
||||
// CHECK:STDOUT: 4: inst70000023
|
||||
// CHECK:STDOUT: 5: inst70000032
|
||||
// CHECK:STDOUT: 6: inst70000033
|
||||
// CHECK:STDOUT: 7: inst70000034
|
||||
// CHECK:STDOUT: inst_block7000000F:
|
||||
// CHECK:STDOUT: 0: instF
|
||||
// CHECK:STDOUT: 1: inst70000010
|
||||
// CHECK:STDOUT: 2: inst7000002F
|
||||
// CHECK:STDOUT: 2: inst70000030
|
||||
// CHECK:STDOUT: value_stores:
|
||||
// CHECK:STDOUT: shared_values:
|
||||
// CHECK:STDOUT: ints: {}
|
||||
|
||||
+424
-53
@@ -105,20 +105,91 @@ fn G() {
|
||||
F(y);
|
||||
}
|
||||
|
||||
// --- fail_todo_form_generic_param.carbon
|
||||
// --- form_generic_param.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_todo_form_generic_param.carbon:[[@LINE+4]]:24: error: semantics TODO: `Support symbolic form bindings` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(Form:! Core.Form, x:? Form);
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn F(Form:! Core.Form, x:? Form);
|
||||
fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
|
||||
fn G() {
|
||||
var x: i32;
|
||||
F(form(var i32), x);
|
||||
}
|
||||
|
||||
// --- fail_todo_composite_generic_form.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
|
||||
fn G() {
|
||||
var x: i32;
|
||||
// CHECK:STDERR: fail_todo_composite_generic_form.carbon:[[@LINE+10]]:3: error: cannot implicitly convert expression of type `(Core.Form, Core.Form)` to `Core.Form` [ConversionFailure]
|
||||
// CHECK:STDERR: F((form(var i32), form(ref i32)), (x, ref x));
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_composite_generic_form.carbon:[[@LINE+7]]:3: note: type `(Core.Form, Core.Form)` does not implement interface `Core.ImplicitAs(Core.Form)` [MissingImplInMemberAccessInContext]
|
||||
// CHECK:STDERR: F((form(var i32), form(ref i32)), (x, ref x));
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_composite_generic_form.carbon:[[@LINE-10]]:6: note: initializing generic parameter `Fm` declared here [InitializingGenericParam]
|
||||
// CHECK:STDERR: fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
F((form(var i32), form(ref i32)), (x, ref x));
|
||||
}
|
||||
|
||||
// --- fail_todo_deduce_generic_form.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F[Fm:! Core.Form](v:? Fm);
|
||||
|
||||
fn G() {
|
||||
var v: i32 = 0;
|
||||
// CHECK:STDERR: fail_todo_deduce_generic_form.carbon:[[@LINE+7]]:3: error: cannot deduce value for generic parameter `Fm` [DeductionIncomplete]
|
||||
// CHECK:STDERR: F(ref v);
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_deduce_generic_form.carbon:[[@LINE-7]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
||||
// CHECK:STDERR: fn F[Fm:! Core.Form](v:? Fm);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
F(ref v);
|
||||
}
|
||||
|
||||
// --- fail_form_generic_arg_not_form.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
|
||||
fn G() {
|
||||
var x: i32;
|
||||
// CHECK:STDERR: fail_form_generic_arg_not_form.carbon:[[@LINE+10]]:3: error: cannot implicitly convert expression of type `type` to `Core.Form` [ConversionFailure]
|
||||
// CHECK:STDERR: F(i32, x);
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_form_generic_arg_not_form.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(Core.Form)` [MissingImplInMemberAccessInContext]
|
||||
// CHECK:STDERR: F(i32, x);
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_form_generic_arg_not_form.carbon:[[@LINE-10]]:6: note: initializing generic parameter `Fm` declared here [InitializingGenericParam]
|
||||
// CHECK:STDERR: fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
F(i32, x);
|
||||
}
|
||||
|
||||
// --- fail_form_generic_missing_ref_tag.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
|
||||
fn G() {
|
||||
var x: i32;
|
||||
// CHECK:STDERR: fail_form_generic_missing_ref_tag.carbon:[[@LINE+8]]:20: error: argument to `ref` parameter not marked with `ref` [RefParamNoRefTag]
|
||||
// CHECK:STDERR: F(form(ref i32), x);
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_form_generic_missing_ref_tag.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: fail_form_generic_missing_ref_tag.carbon:[[@LINE-8]]:29: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: fn F(Fm:! Core.Form, unused x:? Fm) {}
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
F(form(ref i32), x);
|
||||
}
|
||||
|
||||
// --- fail_todo_local_init_form_binding.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -136,7 +207,7 @@ library "[[@TEST_NAME]]";
|
||||
// TODO: this code should fail for a different reason, but right now we don't
|
||||
// have a way to write correct code that reaches the TODO we're exercising here.
|
||||
fn F(Form:! Core.Form) {
|
||||
// CHECK:STDERR: fail_todo_local_symbolic_form_binding.carbon:[[@LINE+4]]:7: error: semantics TODO: `Support symbolic form bindings` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_local_symbolic_form_binding.carbon:[[@LINE+4]]:7: error: semantics TODO: `support local form bindings` [SemanticsTodo]
|
||||
// CHECK:STDERR: let y:? Form = 0;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -201,10 +272,21 @@ fn F() ->? ref i32;
|
||||
|
||||
// --- form_generic_return.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
//@include-in-dumps
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn F(Form:! Core.Form) ->? Form;
|
||||
//@dump-sem-ir-end
|
||||
fn F(Fm:! Core.Form, v:? Fm) ->? Fm {
|
||||
// TODO: This should fail because `Fm` might be `form(var T)` for a
|
||||
// non-copyable `T`.
|
||||
return v;
|
||||
}
|
||||
|
||||
fn G() {
|
||||
var v: i32 = 0;
|
||||
|
||||
var unused x: i32 = F(form(var i32), v);
|
||||
let unused ref y: i32 = F(form(ref i32), ref v);
|
||||
let unused z: i32 = F(form(val i32), v);
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- ref_form_param.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -229,6 +311,7 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.512] {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_15.2: Core.Form = ref_form %i32 [concrete = constants.%.512]
|
||||
// CHECK:STDOUT: %.loc4_15.3: type = type_component_of %.loc4_15.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: ref %i32 = ref_binding x, %x.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -294,6 +377,7 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.795] {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_15.2: Core.Form = init_form %i32 [concrete = constants.%.795]
|
||||
// CHECK:STDOUT: %.loc4_15.3: type = type_component_of %.loc4_15.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: ref %i32 = ref_binding x, %x.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -369,6 +453,7 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: %.loc4_15.1: Core.Form = splice_block %.loc4_15.2 [concrete = constants.%.c2a] {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_15.2: Core.Form = value_form %i32 [concrete = constants.%.c2a]
|
||||
// CHECK:STDOUT: %.loc4_15.3: type = type_component_of %.loc4_15.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: %i32 = value_binding x, %x.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -414,6 +499,7 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: %.loc4_20.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc4_20.2: type = converted %.loc4_20.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc4_15.2: Core.Form = ref_form %.loc4_20.2 [concrete = constants.%.9f9]
|
||||
// CHECK:STDOUT: %.loc4_15.3: type = type_component_of %.loc4_15.2 [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: ref %empty_tuple.type = ref_binding x, %x.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -438,12 +524,13 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %.loc4_17.1: %pattern_type.6b6 = ref_return_pattern [concrete = constants.%.ae0]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %.loc4_17.1, constants.%i32 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %.loc4_17.1, %.loc4_17.3 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_17.2: Core.Form = ref_form %i32 [concrete = constants.%.512]
|
||||
// CHECK:STDOUT: %.loc4_17.3: ref %i32 = ref_return
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %.loc4_17.3
|
||||
// CHECK:STDOUT: %.loc4_17.3: type = type_component_of %.loc4_17.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_17.4: ref %i32 = ref_return
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %.loc4_17.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -483,10 +570,11 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, constants.%i32 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %.loc4_17.2 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4: Core.Form = init_form %i32 [concrete = constants.%.795]
|
||||
// CHECK:STDOUT: %.loc4_17.1: Core.Form = init_form %i32 [concrete = constants.%.795]
|
||||
// CHECK:STDOUT: %.loc4_17.2: type = type_component_of %.loc4_17.1 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -535,12 +623,13 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %.loc4_17.1: %pattern_type.6b6 = value_return_pattern [concrete = constants.%.1a5]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %.loc4_17.1, constants.%i32 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %.loc4_17.1, %.loc4_17.3 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_17.2: Core.Form = value_form %i32 [concrete = constants.%.c2a]
|
||||
// CHECK:STDOUT: %.loc4_17.3: %i32 = value_return
|
||||
// CHECK:STDOUT: %return: %i32 = return_slot %.loc4_17.3
|
||||
// CHECK:STDOUT: %.loc4_17.3: type = type_component_of %.loc4_17.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_17.4: %i32 = value_return
|
||||
// CHECK:STDOUT: %return: %i32 = return_slot %.loc4_17.4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -564,68 +653,350 @@ fn F(Form:! Core.Form) ->? Form;
|
||||
// CHECK:STDOUT: %type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self]
|
||||
// CHECK:STDOUT: %pattern_type.13f: type = pattern_type Core.Form [concrete]
|
||||
// CHECK:STDOUT: %Form.patt: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Form: Core.Form = symbolic_binding Form, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.42f: type = type_component_of %Form [symbolic]
|
||||
// CHECK:STDOUT: %Fm.patt: %pattern_type.13f = symbolic_binding_pattern Fm, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Fm: Core.Form = symbolic_binding Fm, 0 [symbolic]
|
||||
// CHECK:STDOUT: %.42f: type = type_component_of %Fm [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.177: type = pattern_type %.42f [symbolic]
|
||||
// CHECK:STDOUT: %.35a: %pattern_type.177 = splice_inst @F.%.loc4_24.2 [template]
|
||||
// CHECK:STDOUT: %return.patt.5b7: %pattern_type.177 = return_slot_pattern %.35a, %.42f [template]
|
||||
// CHECK:STDOUT: %.94f: <instruction> = out_form_param_pattern_action %Form [template]
|
||||
// CHECK:STDOUT: %.f15: %pattern_type.177 = splice_inst @F.%.loc4_23.2 [template]
|
||||
// CHECK:STDOUT: %v.patt.0b3: %pattern_type.177 = at_binding_pattern v, %.f15 [template]
|
||||
// CHECK:STDOUT: %.677: %pattern_type.177 = splice_inst @F.%.loc4_30.2 [template]
|
||||
// CHECK:STDOUT: %return.patt.113: %pattern_type.177 = return_slot_pattern %.677, %.42f [template]
|
||||
// CHECK:STDOUT: %.cfa: <instruction> = form_param_pattern_action %Fm, v [template]
|
||||
// CHECK:STDOUT: %.26b: %pattern_type.177 = splice_inst %.cfa [template]
|
||||
// CHECK:STDOUT: %v.patt.cda: %pattern_type.177 = at_binding_pattern v, %.26b [template]
|
||||
// CHECK:STDOUT: %.94f: <instruction> = out_form_param_pattern_action %Fm [template]
|
||||
// CHECK:STDOUT: %.1ac: %pattern_type.177 = splice_inst %.94f [template]
|
||||
// CHECK:STDOUT: %return.patt.333: %pattern_type.177 = return_slot_pattern %.1ac, %.42f [template]
|
||||
// CHECK:STDOUT: %.82b: <instruction> = callee_pattern_match_action %.1ac, call_param0 [template]
|
||||
// CHECK:STDOUT: %.095: <instruction> = callee_pattern_match_action %.f15, call_param0 [template]
|
||||
// CHECK:STDOUT: %.efc: <instruction> = callee_pattern_match_action %.677, call_param1 [template]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %require_complete.c9b: <witness> = require_complete_type %.42f [symbolic]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
|
||||
// CHECK:STDOUT: %complete_type.f8a: <witness> = complete_type_witness %i32.builtin [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %v.patt.113: %pattern_type.6b6 = ref_binding_pattern v [concrete]
|
||||
// CHECK:STDOUT: %v.var_patt.68d: %pattern_type.6b6 = var_pattern %v.patt.113 [concrete]
|
||||
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.0ff = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.914: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.845: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness.a23: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.b3c, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.914 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.a23) [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.740: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%i32, %ImplicitAs.facet) [concrete]
|
||||
// CHECK:STDOUT: %.1c5: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.740, %ImplicitAs.facet [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete]
|
||||
// CHECK:STDOUT: %.795: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.a9a4c7.1: %pattern_type.6b6 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_0.3c0: %i32 = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = ref_binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %x.var_patt: %pattern_type.6b6 = var_pattern %x.patt [concrete]
|
||||
// CHECK:STDOUT: %v.param_patt.e9ad17.1: %pattern_type.6b6 = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %v.var_patt.13561f.1: %pattern_type.6b6 = var_pattern %v.param_patt.e9ad17.1 [concrete]
|
||||
// CHECK:STDOUT: %inst.splice_block: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.eb8: %pattern_type.6b6 = splice_block %v.var_patt.13561f.2 [concrete = %v.var_patt.13561f.1] {
|
||||
// CHECK:STDOUT: %v.param_patt.e9ad17.3: %pattern_type.6b6 = ref_param_pattern [concrete = %v.param_patt.e9ad17.1]
|
||||
// CHECK:STDOUT: %v.var_patt.13561f.2: %pattern_type.6b6 = var_pattern %v.param_patt.e9ad17.3 [concrete = %v.var_patt.13561f.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v.patt.b2b: %pattern_type.6b6 = at_binding_pattern v, %v.var_patt.13561f.1 [concrete]
|
||||
// CHECK:STDOUT: %inst.out_param_pattern: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %return.param_patt.a9a4c7.2: %pattern_type.6b6 = out_param_pattern [concrete = %return.param_patt.a9a4c7.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a4c7.1, %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.specific_fn.8ea: <specific function> = specific_function %F, @F(%.795) [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.0e0: <witness> = impl_witness imports.%Copy.impl_witness_table.367, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.3f6: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.4f6: %Int.as.Copy.impl.Op.type.3f6 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.0e0) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.d09: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
||||
// CHECK:STDOUT: %.7a6: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d09, %Copy.facet [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.4f6, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.6b6 = ref_binding_pattern y [concrete]
|
||||
// CHECK:STDOUT: %.512: Core.Form = ref_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %inst.ref_param_pattern: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %v.param_patt.e9ad17.2: %pattern_type.6b6 = ref_param_pattern [concrete = %v.param_patt.e9ad17.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v.patt.5c0: %pattern_type.6b6 = at_binding_pattern v, %v.param_patt.e9ad17.1 [concrete]
|
||||
// CHECK:STDOUT: %.ae0167.1: %pattern_type.6b6 = ref_return_pattern [concrete]
|
||||
// CHECK:STDOUT: %inst.ref_return_pattern: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.ae0167.2: %pattern_type.6b6 = ref_return_pattern [concrete = %.ae0167.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %return.patt.c62: %pattern_type.6b6 = return_slot_pattern %.ae0167.1, %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.specific_fn.0c3: <specific function> = specific_function %F, @F(%.512) [concrete]
|
||||
// CHECK:STDOUT: %z.patt: %pattern_type.6b6 = value_binding_pattern z [concrete]
|
||||
// CHECK:STDOUT: %.c2a: Core.Form = value_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %v.param_patt.733534.1: %pattern_type.6b6 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %inst.value_param_pattern: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %v.param_patt.733534.2: %pattern_type.6b6 = value_param_pattern [concrete = %v.param_patt.733534.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v.patt.971: %pattern_type.6b6 = at_binding_pattern v, %v.param_patt.733534.1 [concrete]
|
||||
// CHECK:STDOUT: %.1a588f.1: %pattern_type.6b6 = value_return_pattern [concrete]
|
||||
// CHECK:STDOUT: %inst.value_return_pattern: <instruction> = inst_value [concrete] {
|
||||
// CHECK:STDOUT: %.1a588f.2: %pattern_type.6b6 = value_return_pattern [concrete = %.1a588f.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %return.patt.45a: %pattern_type.6b6 = return_slot_pattern %.1a588f.1, %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.specific_fn.2f1: <specific function> = specific_function %F, @F(%.c2a) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Self.0e7: %Destroy.type = symbolic_binding Self, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d3e: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Self.0e7) [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.42b: %Destroy.WithSelf.Op.type.d3e = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete]
|
||||
// CHECK:STDOUT: %assoc0.ae8: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.2 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %custom_witness.df9cc1.2: <witness> = custom_witness (%Destroy.Op.1a2547.2), @Destroy [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.d07: %Destroy.type = facet_value %i32, (%custom_witness.df9cc1.2) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.47a: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet.d07) [concrete]
|
||||
// CHECK:STDOUT: %.22e: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.47a, %Destroy.facet.d07 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Form = %Core.Form
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs
|
||||
// CHECK:STDOUT: .Copy = %Core.Copy
|
||||
// CHECK:STDOUT: .Destroy = %Core.Destroy
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Form: type = import_ref Core//prelude/parts/form, Form, loaded [concrete = Core.Form]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.0ff = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: %Core.import_ref.edf: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.845)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.b3c = impl_witness_table (%Core.import_ref.edf), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type]
|
||||
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.5e0)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.367 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: %Core.import_ref.c64: %Destroy.assoc_type = import_ref Core//prelude/parts/destroy, loc{{\d+_\d+}}, loaded [concrete = constants.%assoc0.ae8]
|
||||
// CHECK:STDOUT: %Core.import_ref.918: @Destroy.WithSelf.%Destroy.WithSelf.Op.type (%Destroy.WithSelf.Op.type.d3e) = import_ref Core//prelude/parts/destroy, loc{{\d+_\d+}}, loaded [symbolic = @Destroy.WithSelf.%Destroy.WithSelf.Op (constants.%Destroy.WithSelf.Op.42b)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// 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: %Form.patt.loc4_10.1: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic = %Form.patt.loc4_10.2 (constants.%Form.patt)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_24.1: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_24.6, constants.%.42f [template = %return.patt.loc4_24.2 (constants.%return.patt.5b7)]
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.1: %pattern_type.13f = symbolic_binding_pattern Fm, 0 [symbolic = %Fm.patt.loc4_8.2 (constants.%Fm.patt)]
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.1: @F.%pattern_type (%pattern_type.177) = at_binding_pattern v, %.loc4_23.5 [template = %v.patt.loc4_23.2 (constants.%v.patt.0b3)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.1: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_30.5, %.loc4_34 [template = %return.patt.loc4_30.2 (constants.%return.patt.113)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %Form.ref.loc4_28: Core.Form = name_ref Form, %Form.loc4_10.2 [symbolic = %Form.loc4_10.1 (constants.%Form)]
|
||||
// CHECK:STDOUT: %.loc4_24.6: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.35a)]
|
||||
// CHECK:STDOUT: %.loc4_17: type = splice_block %Form.ref.loc4_17 [concrete = Core.Form] {
|
||||
// CHECK:STDOUT: %.loc4_23.5: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_23.2 [template = %.loc4_23.3 (constants.%.f15)]
|
||||
// CHECK:STDOUT: %Fm.ref.loc4_34: Core.Form = name_ref Fm, %Fm.loc4_8.2 [symbolic = %Fm.loc4_8.1 (constants.%Fm)]
|
||||
// CHECK:STDOUT: %.loc4_34: type = type_component_of %Fm.ref.loc4_34 [symbolic = %.loc4_26.1 (constants.%.42f)]
|
||||
// CHECK:STDOUT: %.loc4_30.5: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_30.2 [template = %.loc4_30.3 (constants.%.677)]
|
||||
// CHECK:STDOUT: %.loc4_15: type = splice_block %Form.ref [concrete = Core.Form] {
|
||||
// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
|
||||
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
|
||||
// CHECK:STDOUT: %Form.ref.loc4_17: type = name_ref Form, imports.%Core.Form [concrete = Core.Form]
|
||||
// CHECK:STDOUT: %Form.ref: type = name_ref Form, imports.%Core.Form [concrete = Core.Form]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Form.loc4_10.2: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form)]
|
||||
// CHECK:STDOUT: %.loc4_24.1: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.5
|
||||
// CHECK:STDOUT: %return: @F.%.loc4_24.3 (%.42f) = return_slot %.loc4_24.1
|
||||
// CHECK:STDOUT: %Fm.loc4_8.2: Core.Form = symbolic_binding Fm, 0 [symbolic = %Fm.loc4_8.1 (constants.%Fm)]
|
||||
// CHECK:STDOUT: %.loc4_23.1: @F.%.loc4_26.1 (%.42f) = splice_inst %.loc4_23.4
|
||||
// CHECK:STDOUT: %.loc4_26.2: Core.Form = splice_block %Fm.ref.loc4_26 [symbolic = %Fm.loc4_8.1 (constants.%Fm)] {
|
||||
// CHECK:STDOUT: %Fm.ref.loc4_26: Core.Form = name_ref Fm, %Fm.loc4_8.2 [symbolic = %Fm.loc4_8.1 (constants.%Fm)]
|
||||
// CHECK:STDOUT: %.loc4_26.3: type = type_component_of %Fm.ref.loc4_26 [symbolic = %.loc4_26.1 (constants.%.42f)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v: @F.%.loc4_26.1 (%.42f) = wrapper_binding v, %.loc4_23.1
|
||||
// CHECK:STDOUT: %.loc4_30.1: @F.%.loc4_26.1 (%.42f) = splice_inst %.loc4_30.4
|
||||
// CHECK:STDOUT: %return: @F.%.loc4_26.1 (%.42f) = return_slot %.loc4_30.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%Fm.loc4_8.2: Core.Form) {
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.2: %pattern_type.13f = symbolic_binding_pattern Fm, 0 [symbolic = %Fm.patt.loc4_8.2 (constants.%Fm.patt)]
|
||||
// CHECK:STDOUT: %Fm.loc4_8.1: Core.Form = symbolic_binding Fm, 0 [symbolic = %Fm.loc4_8.1 (constants.%Fm)]
|
||||
// CHECK:STDOUT: %.loc4_26.1: type = type_component_of %Fm.loc4_8.1 [symbolic = %.loc4_26.1 (constants.%.42f)]
|
||||
// CHECK:STDOUT: %.loc4_23.2: <instruction> = form_param_pattern_action %Fm.ref.loc4_26, v [template]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %.loc4_26.1 [symbolic = %pattern_type (constants.%pattern_type.177)]
|
||||
// CHECK:STDOUT: %.loc4_23.3: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_23.2 [template = %.loc4_23.3 (constants.%.f15)]
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.2: @F.%pattern_type (%pattern_type.177) = at_binding_pattern v, %.loc4_23.3 [template = %v.patt.loc4_23.2 (constants.%v.patt.0b3)]
|
||||
// CHECK:STDOUT: %.loc4_30.2: <instruction> = out_form_param_pattern_action %Fm.ref.loc4_34 [template]
|
||||
// CHECK:STDOUT: %.loc4_30.3: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_30.2 [template = %.loc4_30.3 (constants.%.677)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.2: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_30.3, %.loc4_26.1 [template = %return.patt.loc4_30.2 (constants.%return.patt.113)]
|
||||
// CHECK:STDOUT: %.loc4_23.4: <instruction> = callee_pattern_match_action constants.%.f15, call_param0 [template]
|
||||
// CHECK:STDOUT: %.loc4_30.4: <instruction> = callee_pattern_match_action constants.%.677, call_param1 [template]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %.loc4_26.1 [symbolic = %require_complete (constants.%require_complete.c9b)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%.loc4_23.1: @F.%.loc4_26.1 (%.42f)) -> out %.loc4_30.1:? %Fm {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %v.ref: @F.%.loc4_26.1 (%.42f) = name_ref v, %v
|
||||
// CHECK:STDOUT: return %v.ref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @F(%Form.loc4_10.2: Core.Form) {
|
||||
// CHECK:STDOUT: %Form.patt.loc4_10.2: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic = %Form.patt.loc4_10.2 (constants.%Form.patt)]
|
||||
// CHECK:STDOUT: %Form.loc4_10.1: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form)]
|
||||
// CHECK:STDOUT: %.loc4_24.2: <instruction> = out_form_param_pattern_action %Form.ref.loc4_28 [template]
|
||||
// CHECK:STDOUT: %.loc4_24.3: type = type_component_of %Form.loc4_10.1 [symbolic = %.loc4_24.3 (constants.%.42f)]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %.loc4_24.3 [symbolic = %pattern_type (constants.%pattern_type.177)]
|
||||
// CHECK:STDOUT: %.loc4_24.4: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.35a)]
|
||||
// CHECK:STDOUT: %return.patt.loc4_24.2: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_24.4, %.loc4_24.3 [template = %return.patt.loc4_24.2 (constants.%return.patt.5b7)]
|
||||
// CHECK:STDOUT: %.loc4_24.5: <instruction> = callee_pattern_match_action %.loc4_24.6, call_param0 [template]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn() -> out %.loc4_24.1:? %Form;
|
||||
// CHECK:STDOUT: fn @G() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %v.patt: %pattern_type.6b6 = ref_binding_pattern v [concrete = constants.%v.patt.113]
|
||||
// CHECK:STDOUT: %v.var_patt: %pattern_type.6b6 = var_pattern %v.patt [concrete = constants.%v.var_patt.68d]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v.var.loc11: ref %i32 = var %v.var_patt
|
||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0.loc11: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
|
||||
// CHECK:STDOUT: %bound_method.loc11_3.1: <bound method> = bound_method %int_0, %impl.elem0.loc11 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc11: <specific function> = specific_function %impl.elem0.loc11, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc11_3.2: <bound method> = bound_method %int_0, %specific_fn.loc11 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc11_3.2(%int_0) [concrete = constants.%int_0.3c0]
|
||||
// CHECK:STDOUT: %.loc11: init %i32 = converted %int_0, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.3c0]
|
||||
// CHECK:STDOUT: assign %v.var.loc11, %.loc11
|
||||
// CHECK:STDOUT: %i32.loc11: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %v: ref %i32 = ref_binding v, %v.var.loc11
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = ref_binding_pattern x [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %x.var_patt: %pattern_type.6b6 = var_pattern %x.patt [concrete = constants.%x.var_patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x.var: ref %i32 = var %x.var_patt
|
||||
// CHECK:STDOUT: %F.ref.loc13: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %i32.loc13_34: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc13_30: Core.Form = init_form %i32.loc13_34 [concrete = constants.%.795]
|
||||
// CHECK:STDOUT: %v.ref.loc13: ref %i32 = name_ref v, %v
|
||||
// CHECK:STDOUT: %F.specific_fn.loc13: <specific function> = specific_function %F.ref.loc13, @F(constants.%.795) [concrete = constants.%F.specific_fn.8ea]
|
||||
// CHECK:STDOUT: %.loc13_40: %i32 = acquire_value %v.ref.loc13
|
||||
// CHECK:STDOUT: %impl.elem0.loc13: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
||||
// CHECK:STDOUT: %bound_method.loc13_40.1: <bound method> = bound_method %.loc13_40, %impl.elem0.loc13
|
||||
// CHECK:STDOUT: %specific_fn.loc13: <specific function> = specific_function %impl.elem0.loc13, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc13_40.2: <bound method> = bound_method %.loc13_40, %specific_fn.loc13
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc13_40.2(%.loc13_40)
|
||||
// CHECK:STDOUT: %v.var.1: ref %i32 = var constants.%v.var_patt.13561f.1
|
||||
// CHECK:STDOUT: assign %v.var.1, %Int.as.Copy.impl.Op.call
|
||||
// CHECK:STDOUT: %F.call.loc13: init %i32 = call %F.specific_fn.loc13(%v.var.1)
|
||||
// CHECK:STDOUT: assign %x.var, %F.call.loc13
|
||||
// CHECK:STDOUT: %i32.loc13_17: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: ref %i32 = ref_binding x, %x.var
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.6b6 = ref_binding_pattern y [concrete = constants.%y.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.ref.loc14: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %i32.loc14_38: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc14_34: Core.Form = ref_form %i32.loc14_38 [concrete = constants.%.512]
|
||||
// CHECK:STDOUT: %v.ref.loc14: ref %i32 = name_ref v, %v
|
||||
// CHECK:STDOUT: %.loc14_44: %i32 = ref_tag %v.ref.loc14
|
||||
// CHECK:STDOUT: %F.specific_fn.loc14: <specific function> = specific_function %F.ref.loc14, @F(constants.%.512) [concrete = constants.%F.specific_fn.0c3]
|
||||
// CHECK:STDOUT: %F.call.loc14: ref %i32 = call %F.specific_fn.loc14(%v.ref.loc14)
|
||||
// CHECK:STDOUT: %i32.loc14_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %y: ref %i32 = ref_binding y, %F.call.loc14
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %z.patt: %pattern_type.6b6 = value_binding_pattern z [concrete = constants.%z.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.ref.loc15: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %i32.loc15_34: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc15_30: Core.Form = value_form %i32.loc15_34 [concrete = constants.%.c2a]
|
||||
// CHECK:STDOUT: %v.ref.loc15: ref %i32 = name_ref v, %v
|
||||
// CHECK:STDOUT: %F.specific_fn.loc15: <specific function> = specific_function %F.ref.loc15, @F(constants.%.c2a) [concrete = constants.%F.specific_fn.2f1]
|
||||
// CHECK:STDOUT: %.loc15_40: %i32 = acquire_value %v.ref.loc15
|
||||
// CHECK:STDOUT: %F.call.loc15: %i32 = call %F.specific_fn.loc15(%.loc15_40)
|
||||
// CHECK:STDOUT: %i32.loc15_17: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %z: %i32 = value_binding z, %F.call.loc15
|
||||
// CHECK:STDOUT: %Op.ref: %Destroy.assoc_type = name_ref Op, imports.%Core.import_ref.c64 [concrete = constants.%assoc0.ae8]
|
||||
// CHECK:STDOUT: %impl.elem0.1: %.22e = impl_witness_access constants.%custom_witness.df9cc1.2, element0 [concrete = constants.%Destroy.Op.1a2547.2]
|
||||
// CHECK:STDOUT: %bound_method.1: <bound method> = bound_method %v.var.1, %impl.elem0.1
|
||||
// CHECK:STDOUT: %Destroy.Op.call.1: init %empty_tuple.type = call %bound_method.1(%v.var.1)
|
||||
// CHECK:STDOUT: %Destroy.Op.bound.loc13: <bound method> = bound_method %x.var, constants.%Destroy.Op.1a2547.2
|
||||
// CHECK:STDOUT: %Destroy.Op.call.loc13: init %empty_tuple.type = call %Destroy.Op.bound.loc13(%x.var)
|
||||
// CHECK:STDOUT: %Destroy.Op.bound.loc11: <bound method> = bound_method %v.var.loc11, constants.%Destroy.Op.1a2547.2
|
||||
// CHECK:STDOUT: %Destroy.Op.call.loc11: init %empty_tuple.type = call %Destroy.Op.bound.loc11(%v.var.loc11)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%Form) {
|
||||
// CHECK:STDOUT: %Form.patt.loc4_10.2 => constants.%Form.patt
|
||||
// CHECK:STDOUT: %Form.loc4_10.1 => constants.%Form
|
||||
// CHECK:STDOUT: %.loc4_24.2 => constants.%.94f
|
||||
// CHECK:STDOUT: %.loc4_24.3 => constants.%.42f
|
||||
// CHECK:STDOUT: fn @Destroy.Op.1(%self.param: ref %i32.builtin) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.Op.2(%self.param: ref %i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%Fm) {
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.2 => constants.%Fm.patt
|
||||
// CHECK:STDOUT: %Fm.loc4_8.1 => constants.%Fm
|
||||
// CHECK:STDOUT: %.loc4_26.1 => constants.%.42f
|
||||
// CHECK:STDOUT: %.loc4_23.2 => constants.%.cfa
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.177
|
||||
// CHECK:STDOUT: %.loc4_24.4 => constants.%.1ac
|
||||
// CHECK:STDOUT: %return.patt.loc4_24.2 => constants.%return.patt.333
|
||||
// CHECK:STDOUT: %.loc4_24.5 => constants.%.82b
|
||||
// CHECK:STDOUT: %.loc4_23.3 => constants.%.26b
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.2 => constants.%v.patt.cda
|
||||
// CHECK:STDOUT: %.loc4_30.2 => constants.%.94f
|
||||
// CHECK:STDOUT: %.loc4_30.3 => constants.%.1ac
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.2 => constants.%return.patt.333
|
||||
// CHECK:STDOUT: %.loc4_23.4 => constants.%.095
|
||||
// CHECK:STDOUT: %.loc4_30.4 => constants.%.efc
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%.795) {
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.2 => constants.%Fm.patt
|
||||
// CHECK:STDOUT: %Fm.loc4_8.1 => constants.%.795
|
||||
// CHECK:STDOUT: %.loc4_26.1 => constants.%i32
|
||||
// CHECK:STDOUT: %.loc4_23.2 => constants.%inst.splice_block
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.6b6
|
||||
// CHECK:STDOUT: %.loc4_23.3 => constants.%v.var_patt.13561f.1
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.2 => constants.%v.patt.b2b
|
||||
// CHECK:STDOUT: %.loc4_30.2 => constants.%inst.out_param_pattern
|
||||
// CHECK:STDOUT: %.loc4_30.3 => constants.%return.param_patt.a9a4c7.1
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.2 => constants.%return.patt.e1b
|
||||
// CHECK:STDOUT: %.loc4_23.4 => constants.%.095
|
||||
// CHECK:STDOUT: %.loc4_30.4 => constants.%.efc
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%.512) {
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.2 => constants.%Fm.patt
|
||||
// CHECK:STDOUT: %Fm.loc4_8.1 => constants.%.512
|
||||
// CHECK:STDOUT: %.loc4_26.1 => constants.%i32
|
||||
// CHECK:STDOUT: %.loc4_23.2 => constants.%inst.ref_param_pattern
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.6b6
|
||||
// CHECK:STDOUT: %.loc4_23.3 => constants.%v.param_patt.e9ad17.1
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.2 => constants.%v.patt.5c0
|
||||
// CHECK:STDOUT: %.loc4_30.2 => constants.%inst.ref_return_pattern
|
||||
// CHECK:STDOUT: %.loc4_30.3 => constants.%.ae0167.1
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.2 => constants.%return.patt.c62
|
||||
// CHECK:STDOUT: %.loc4_23.4 => constants.%.095
|
||||
// CHECK:STDOUT: %.loc4_30.4 => constants.%.efc
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @F(constants.%.c2a) {
|
||||
// CHECK:STDOUT: %Fm.patt.loc4_8.2 => constants.%Fm.patt
|
||||
// CHECK:STDOUT: %Fm.loc4_8.1 => constants.%.c2a
|
||||
// CHECK:STDOUT: %.loc4_26.1 => constants.%i32
|
||||
// CHECK:STDOUT: %.loc4_23.2 => constants.%inst.value_param_pattern
|
||||
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.6b6
|
||||
// CHECK:STDOUT: %.loc4_23.3 => constants.%v.param_patt.733534.1
|
||||
// CHECK:STDOUT: %v.patt.loc4_23.2 => constants.%v.patt.971
|
||||
// CHECK:STDOUT: %.loc4_30.2 => constants.%inst.value_return_pattern
|
||||
// CHECK:STDOUT: %.loc4_30.3 => constants.%.1a588f.1
|
||||
// CHECK:STDOUT: %return.patt.loc4_30.2 => constants.%return.patt.45a
|
||||
// CHECK:STDOUT: %.loc4_23.4 => constants.%.095
|
||||
// CHECK:STDOUT: %.loc4_30.4 => constants.%.efc
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/form.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/fail_todo_form_thunk.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/fail_todo_form_thunk.carbon
|
||||
|
||||
interface I {
|
||||
let T:! type;
|
||||
let Fm:! Core.Form;
|
||||
// CHECK:STDERR: fail_todo_form_thunk.carbon:[[@LINE+4]]:8: error: semantics TODO: `Support symbolic form bindings` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(x:? Fm, y: T);
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn F(x:? Fm, y: T);
|
||||
}
|
||||
|
||||
class C {
|
||||
impl as I where .T = () and .Fm = form(ref ()) {
|
||||
fn F(x:? form(ref ()), ());
|
||||
}
|
||||
}
|
||||
+97
-1
@@ -125,6 +125,22 @@ impl B as X {
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- form_parameter.carbon
|
||||
|
||||
interface I {
|
||||
let T:! type;
|
||||
let Fm:! Core.Form;
|
||||
fn F(x:? Fm, y: {.a: (), .b: ()});
|
||||
}
|
||||
|
||||
class C {
|
||||
impl as I where .T = () and .Fm = form(ref ()) {
|
||||
//@dump-sem-ir-begin
|
||||
fn F(x:? form(ref ()), y: {.b: (), .a: ()});
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
}
|
||||
|
||||
// --- fail_inheritance_value_conversion_copy_return.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
@@ -330,7 +346,6 @@ impl () as I({}) {
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
|
||||
// CHECK:STDOUT: --- struct_conversion.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -871,6 +886,87 @@ impl () as I({}) {
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- form_parameter.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
|
||||
// CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %empty_tuple.type, .b: %empty_tuple.type} [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %.9f9: Core.Form = ref_form %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt.363cc0.1: %pattern_type.cb1 = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt.b18d0b.1: %pattern_type.cb1 = at_binding_pattern x, %x.param_patt.363cc0.1 [concrete]
|
||||
// CHECK:STDOUT: %struct_type.b.a: type = struct_type {.b: %empty_tuple.type, .a: %empty_tuple.type} [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.120: type = pattern_type %struct_type.b.a [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt.618: %pattern_type.120 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %y.patt.b7b: %pattern_type.120 = at_binding_pattern y, %y.param_patt.618 [concrete]
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.type.a24f58.1: type = fn_type @C.as.I.impl.F.loc11_48.1 [concrete]
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.4c1488.1: %C.as.I.impl.F.type.a24f58.1 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete]
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.type.a24f58.2: type = fn_type @C.as.I.impl.F.loc11_48.2 [concrete]
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.4c1488.2: %C.as.I.impl.F.type.a24f58.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @C.as.I.impl: %Self.ref as %.loc9_13 {
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.decl.loc11_48.1: %C.as.I.impl.F.type.a24f58.1 = fn_decl @C.as.I.impl.F.loc11_48.1 [concrete = constants.%C.as.I.impl.F.4c1488.1] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%x.param_patt.363cc0.1]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = at_binding_pattern x, %x.param_patt [concrete = constants.%x.patt.b18d0b.1]
|
||||
// CHECK:STDOUT: %y.param_patt: %pattern_type.120 = value_param_pattern [concrete = constants.%y.param_patt.618]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.120 = at_binding_pattern y, %y.param_patt [concrete = constants.%y.patt.b7b]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: ref %empty_tuple.type = ref_param call_param0
|
||||
// CHECK:STDOUT: %.loc11_19.1: Core.Form = splice_block %.loc11_19.2 [concrete = constants.%.9f9] {
|
||||
// CHECK:STDOUT: %.loc11_24.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc11_24.2: type = converted %.loc11_24.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc11_19.2: Core.Form = ref_form %.loc11_24.2 [concrete = constants.%.9f9]
|
||||
// CHECK:STDOUT: %.loc11_19.3: type = type_component_of %.loc11_19.2 [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: ref %empty_tuple.type = ref_binding x, %x.param
|
||||
// CHECK:STDOUT: %y.param: %struct_type.b.a = value_param call_param1
|
||||
// CHECK:STDOUT: %.loc11_46: type = splice_block %struct_type.b.a [concrete = constants.%struct_type.b.a] {
|
||||
// CHECK:STDOUT: %.loc11_37.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc11_37.2: type = converted %.loc11_37.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc11_45.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc11_45.2: type = converted %.loc11_45.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %struct_type.b.a: type = struct_type {.b: %empty_tuple.type, .a: %empty_tuple.type} [concrete = constants.%struct_type.b.a]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y: %struct_type.b.a = value_binding y, %y.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.decl.loc11_48.2: %C.as.I.impl.F.type.a24f58.2 = fn_decl @C.as.I.impl.F.loc11_48.2 [concrete = constants.%C.as.I.impl.F.4c1488.2] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .F = %C.as.I.impl.F.decl.loc11_48.1
|
||||
// CHECK:STDOUT: extend %.loc9_13
|
||||
// CHECK:STDOUT: witness = %I.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @C {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%C
|
||||
// CHECK:STDOUT: .I = <poisoned>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C.as.I.impl.F.loc11_48.1(%x.param: ref %empty_tuple.type, %y.param: %struct_type.b.a);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C.as.I.impl.F.loc11_48.2(%x.param: ref %empty_tuple.type, %y.param: %struct_type.a.b) [thunk @C.as.I.impl.%C.as.I.impl.F.decl.loc11_48.1 for @I.WithSelf.%I.WithSelf.F.decl, @I.WithSelf.F(constants.%I.facet)] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %F.ref: %C.as.I.impl.F.type.a24f58.1 = name_ref F, @C.as.I.impl.%C.as.I.impl.F.decl.loc11_48.1 [concrete = constants.%C.as.I.impl.F.4c1488.1]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %F.ref(%x.param, %.5)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_inheritance_value_conversion_copy_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
|
||||
@@ -120,6 +120,11 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
||||
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
||||
}
|
||||
|
||||
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::WrapperBinding inst) -> void {
|
||||
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
||||
}
|
||||
|
||||
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::BlockArg inst) -> void {
|
||||
context.SetLocal(
|
||||
|
||||
@@ -22,8 +22,15 @@ static auto AsAnyInstId(IdAndKind arg) -> InstId {
|
||||
return arg.As<SemIR::AbsoluteInstId>();
|
||||
}
|
||||
|
||||
struct ExprCategoryResult {
|
||||
ExprCategory category;
|
||||
InstId inner_inst_id;
|
||||
};
|
||||
|
||||
// Returns the expression category of `inst_id`, and the ID of the innermost
|
||||
// inst visited while determining that category.
|
||||
static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
|
||||
-> ExprCategory {
|
||||
-> ExprCategoryResult {
|
||||
// The overall expression category if the current instruction is a value
|
||||
// expression.
|
||||
ExprCategory value_category = ExprCategory::Value;
|
||||
@@ -34,8 +41,10 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
|
||||
|
||||
// If this instruction kind has a fixed category, return it.
|
||||
if (auto fixed_category = category_from_kind.TryAsFixedCategory()) {
|
||||
return *fixed_category == ExprCategory::Value ? value_category
|
||||
: *fixed_category;
|
||||
return {.category = *fixed_category == ExprCategory::Value
|
||||
? value_category
|
||||
: *fixed_category,
|
||||
.inner_inst_id = inst_id};
|
||||
}
|
||||
|
||||
// Handle any special cases that use
|
||||
@@ -107,8 +116,10 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
|
||||
// operand.
|
||||
switch (*category_from_kind.TryAsComputedCategory()) {
|
||||
case ComputedExprCategory::ValueIfHasType: {
|
||||
return untyped_inst.kind().has_type() ? value_category
|
||||
: ExprCategory::NotExpr;
|
||||
return {.category = untyped_inst.kind().has_type()
|
||||
? value_category
|
||||
: ExprCategory::NotExpr,
|
||||
.inner_inst_id = inst_id};
|
||||
}
|
||||
|
||||
case ComputedExprCategory::SameAsFirstOperand: {
|
||||
@@ -127,7 +138,7 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
|
||||
case TypedInstT::Kind: { \
|
||||
auto category = handle_special_case(untyped_inst.As<TypedInstT>()); \
|
||||
if (category.has_value()) { \
|
||||
return *category; \
|
||||
return {.category = *category, .inner_inst_id = inst_id}; \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
@@ -139,7 +150,7 @@ static auto GetExprCategoryImpl(const File* ir, InstId inst_id)
|
||||
}
|
||||
|
||||
auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
|
||||
return GetExprCategoryImpl(&file, inst_id);
|
||||
return GetExprCategoryImpl(&file, inst_id).category;
|
||||
}
|
||||
|
||||
auto FindStorageArgForInitializer(const File& sem_ir, InstId init_id,
|
||||
@@ -258,11 +269,11 @@ static auto GetDecomposedFormKindForType(const File& sem_ir, TypeId type_id)
|
||||
return FormInfo::Primitive;
|
||||
}
|
||||
|
||||
auto GetFormInfo(const File& sem_ir, InstId inst_id) -> FormInfo {
|
||||
auto GetFormInfo(const File& sem_ir, SemIR::InstId inst_id) -> FormInfo {
|
||||
auto inst = sem_ir.insts().Get(inst_id);
|
||||
|
||||
ExprCategory category = GetExprCategory(sem_ir, inst_id);
|
||||
if (inst.type_id() == ErrorInst::TypeId) {
|
||||
auto [category, inner_inst_id] = GetExprCategoryImpl(&sem_ir, inst_id);
|
||||
if (inst.type_id() == SemIR::ErrorInst::TypeId) {
|
||||
// TODO: Should `GetExprCategory` do this?
|
||||
category = ExprCategory::Error;
|
||||
}
|
||||
@@ -275,10 +286,25 @@ auto GetFormInfo(const File& sem_ir, InstId inst_id) -> FormInfo {
|
||||
sem_ir.types().GetAsInst(inst.type_id()));
|
||||
}
|
||||
|
||||
auto form_inst_id = InstId::None;
|
||||
if (category == ExprCategory::Dependent) {
|
||||
kind = FormInfo::Dependent;
|
||||
// TODO: Generalize this logic to handle other kinds of form-dependent insts
|
||||
// besides references to `:?` bindings.
|
||||
auto splice = sem_ir.insts().GetAs<SpliceInst>(inner_inst_id);
|
||||
auto param_action =
|
||||
sem_ir.insts().GetAs<CalleePatternMatchAction>(splice.inst_id);
|
||||
auto args = sem_ir.bundles().Get(param_action.args_id);
|
||||
splice = sem_ir.insts().GetAs<SpliceInst>(args.pattern_id);
|
||||
auto pattern = sem_ir.insts().GetAs<FormParamPatternAction>(splice.inst_id);
|
||||
form_inst_id = pattern.form_id;
|
||||
}
|
||||
|
||||
return {.kind = kind,
|
||||
.category = category,
|
||||
.type_id = inst.type_id(),
|
||||
.constant_id = sem_ir.constant_values().Get(inst_id),
|
||||
.form_inst_id = form_inst_id,
|
||||
.loc_id = LocId(inst_id),
|
||||
.inst_id = inst_id};
|
||||
}
|
||||
@@ -324,12 +350,15 @@ auto VisitTupleElementForms(const File& sem_ir, FormInfo form,
|
||||
|
||||
for (auto [type_inst_id, const_inst_id] :
|
||||
llvm::zip_longest(element_type_inst_ids, tuple_const_inst_ids)) {
|
||||
// TODO: figure out how to update the category if it's `Mixed`, and
|
||||
// how to populate `form_inst_id` if the updated category is `Dependent`.
|
||||
visitor({.kind = FormInfo::Primitive,
|
||||
.category = form.category,
|
||||
.type_id = sem_ir.types().GetTypeIdForTypeInstId(*type_inst_id),
|
||||
.constant_id = const_inst_id
|
||||
? sem_ir.constant_values().Get(*const_inst_id)
|
||||
: ConstantId::NotConstant,
|
||||
.form_inst_id = InstId::None,
|
||||
.loc_id = form.loc_id,
|
||||
.inst_id = InstId::None});
|
||||
}
|
||||
@@ -357,6 +386,8 @@ auto VisitStructElementForms(const File& sem_ir, FormInfo form,
|
||||
|
||||
for (auto [field, const_inst_id] :
|
||||
llvm::zip_longest(fields, struct_const_inst_ids)) {
|
||||
// TODO: figure out how to update the category if it's `Mixed`, and
|
||||
// how to populate `form_inst_id` if the updated category is `Dependent`.
|
||||
visitor(
|
||||
{.kind = FormInfo::Primitive,
|
||||
.category = form.category,
|
||||
@@ -364,6 +395,7 @@ auto VisitStructElementForms(const File& sem_ir, FormInfo form,
|
||||
.constant_id = const_inst_id
|
||||
? sem_ir.constant_values().Get(*const_inst_id)
|
||||
: ConstantId::NotConstant,
|
||||
.form_inst_id = InstId::None,
|
||||
.loc_id = form.loc_id,
|
||||
.inst_id = InstId::None});
|
||||
}
|
||||
|
||||
@@ -42,9 +42,15 @@ auto FindStorageArgForInitializer(const File& sem_ir, InstId init_id,
|
||||
// Information about the form of an expression.
|
||||
struct FormInfo {
|
||||
enum Kind : int8_t {
|
||||
// A primitive form (which has independent type, category, phase, and
|
||||
// value).
|
||||
Primitive,
|
||||
// A tuple form.
|
||||
Tuple,
|
||||
// A struct form.
|
||||
Struct,
|
||||
// A form whose kind depends on the value of one or more symbolic bindings.
|
||||
Dependent,
|
||||
};
|
||||
|
||||
// The kind of the form.
|
||||
@@ -57,6 +63,9 @@ struct FormInfo {
|
||||
SemIR::TypeId type_id;
|
||||
// The constant value component of the form.
|
||||
SemIR::ConstantId constant_id;
|
||||
// For a Dependent form, this is an inst whose constant value represents
|
||||
// the form. Otherwise, it is None.
|
||||
SemIR::InstId form_inst_id;
|
||||
// The location of the expression whose form this is.
|
||||
SemIR::LocId loc_id;
|
||||
// The underlying instruction, if there is one. This is only present in order
|
||||
|
||||
@@ -33,6 +33,7 @@ using IdKind = TypeEnum<
|
||||
AssociatedConstantId,
|
||||
BoolValue,
|
||||
BundleId<CalleePatternMatchAction::Args>,
|
||||
BundleId<CallerPatternMatchAction::Args>,
|
||||
CallParamIndex,
|
||||
CharId,
|
||||
ClangDeclId,
|
||||
|
||||
@@ -143,7 +143,8 @@ struct AnyBindingPattern {
|
||||
X(::Carbon::SemIR::AliasBinding) Sep() \
|
||||
X(::Carbon::SemIR::RefBinding) Sep() \
|
||||
X(::Carbon::SemIR::SymbolicBinding) Sep() \
|
||||
X(::Carbon::SemIR::ValueBinding)
|
||||
X(::Carbon::SemIR::ValueBinding) Sep() \
|
||||
X(::Carbon::SemIR::WrapperBinding)
|
||||
// clang-format on
|
||||
|
||||
#define AnyBinding_CARBON_KIND_ANY_EXPAND \
|
||||
@@ -160,6 +161,7 @@ struct AnyBinding {
|
||||
|
||||
// The value is inline in the inst so that value access doesn't require an
|
||||
// indirection.
|
||||
// TODO: rename to `result_id` since it's not necessarily a value.
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ CARBON_SEM_IR_INST_KIND(BranchIf)
|
||||
CARBON_SEM_IR_INST_KIND(BranchWithArg)
|
||||
CARBON_SEM_IR_INST_KIND(Call)
|
||||
CARBON_SEM_IR_INST_KIND(CalleePatternMatchAction)
|
||||
CARBON_SEM_IR_INST_KIND(CallerPatternMatchAction)
|
||||
CARBON_SEM_IR_INST_KIND(CharLiteralType)
|
||||
CARBON_SEM_IR_INST_KIND(CharLiteralValue)
|
||||
CARBON_SEM_IR_INST_KIND(ClassDecl)
|
||||
@@ -183,6 +184,7 @@ CARBON_SEM_IR_INST_KIND(VtableType)
|
||||
CARBON_SEM_IR_INST_KIND(VtablePtr)
|
||||
CARBON_SEM_IR_INST_KIND(WhereExpr)
|
||||
CARBON_SEM_IR_INST_KIND(WitnessType)
|
||||
CARBON_SEM_IR_INST_KIND(WrapperBinding)
|
||||
CARBON_SEM_IR_INST_KIND(WrapperBindingPattern)
|
||||
|
||||
#undef CARBON_SEM_IR_INST_KIND
|
||||
|
||||
@@ -439,7 +439,9 @@ class InstKind::Definition : public InstKind {
|
||||
// kind is always symbolic when it's a value, then it's always symbolic when
|
||||
// it's a type.
|
||||
return is_type() != InstIsType::Never &&
|
||||
(constant_kind() == InstConstantKind::SymbolicOnly ||
|
||||
(constant_kind() == InstConstantKind::Indirect ||
|
||||
constant_kind() == InstConstantKind::ConstantInstAction ||
|
||||
constant_kind() == InstConstantKind::SymbolicOnly ||
|
||||
constant_kind() == InstConstantKind::SymbolicOrReference);
|
||||
}
|
||||
|
||||
|
||||
@@ -453,6 +453,11 @@ class Stringifier {
|
||||
">");
|
||||
}
|
||||
|
||||
auto StringifyInst(InstId /*inst_id*/, SpliceInst inst) -> void {
|
||||
*out_ << "<splice of ";
|
||||
step_stack_->Push(inst.inst_id, ">");
|
||||
}
|
||||
|
||||
// Determine the specific interface that an impl witness instruction provides
|
||||
// an implementation of.
|
||||
// TODO: Should we track this in the type?
|
||||
|
||||
@@ -388,11 +388,13 @@ struct Call {
|
||||
InstBlockId args_id;
|
||||
};
|
||||
|
||||
// An action that performs callee-side pattern matching for a single syntactic
|
||||
// parameter.
|
||||
struct CalleePatternMatchAction {
|
||||
static constexpr auto Kind =
|
||||
InstKind::CalleePatternMatchAction.Define<Parse::NodeId>(
|
||||
{.ir_name = "callee_pattern_match_action",
|
||||
.expr_category = ExprCategory::Value,
|
||||
.expr_category = ExprCategory::Dependent,
|
||||
.constant_kind = InstConstantKind::InstAction,
|
||||
.is_lowered = false});
|
||||
|
||||
@@ -400,7 +402,9 @@ struct CalleePatternMatchAction {
|
||||
// a bundle to validate `BundleStore` until a followup PR introduces a
|
||||
// "real" use case.
|
||||
struct Args {
|
||||
// The parameter pattern to be matched.
|
||||
MetaInstId pattern_id;
|
||||
// The index of the parameter in the `Call` parameter list.
|
||||
CallParamIndex parent_index;
|
||||
};
|
||||
|
||||
@@ -408,6 +412,29 @@ struct CalleePatternMatchAction {
|
||||
BundleId<Args> args_id;
|
||||
};
|
||||
|
||||
// An action that performs caller-side pattern matching for a single syntactic
|
||||
// parameter.
|
||||
struct CallerPatternMatchAction {
|
||||
static constexpr auto Kind =
|
||||
InstKind::CallerPatternMatchAction.Define<Parse::NodeId>(
|
||||
{.ir_name = "caller_pattern_match_action",
|
||||
.expr_category = ExprCategory::Dependent,
|
||||
.constant_kind = InstConstantKind::InstAction,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
|
||||
struct Args {
|
||||
// The parameter pattern to be matched.
|
||||
MetaInstId pattern_id;
|
||||
// The corresponding syntactic argument.
|
||||
MetaInstId arg_id;
|
||||
// The specific to substitute into the parameter pattern.
|
||||
SpecificId callee_specific_id;
|
||||
};
|
||||
BundleId<Args> args_id;
|
||||
};
|
||||
|
||||
// A unicode code point character literal. This type only provides compile-time
|
||||
// operations, and is represented as an empty type at runtime.
|
||||
//
|
||||
@@ -2062,12 +2089,11 @@ struct TupleValue {
|
||||
// Extracts the type component of `form_inst_id`, which must have type
|
||||
// `Core.Form`.
|
||||
struct TypeComponentOf {
|
||||
static constexpr auto Kind =
|
||||
InstKind::TypeComponentOf.Define<Parse::NoneNodeId>(
|
||||
{.ir_name = "type_component_of",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.is_lowered = false});
|
||||
static constexpr auto Kind = InstKind::TypeComponentOf.Define<Parse::NodeId>(
|
||||
{.ir_name = "type_component_of",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.is_lowered = false});
|
||||
|
||||
// Always TypeType.
|
||||
TypeId type_id;
|
||||
@@ -2382,6 +2408,20 @@ struct WhereExpr {
|
||||
// standard type and be removed.
|
||||
using WitnessType = SingletonTypeInst<InstKind::WitnessType, "<witness>">;
|
||||
|
||||
// Binds a name to a result (which must not be an initializing expression),
|
||||
// forwarding its type and category. See `AnyBinding` for member documentation.
|
||||
//
|
||||
// TODO: replace RefBinding and ValueBinding (and possibly SymbolicBinding) with
|
||||
// WrapperBinding.
|
||||
struct WrapperBinding {
|
||||
static constexpr auto Kind = InstKind::WrapperBinding.Define<Parse::NodeId>(
|
||||
{.ir_name = "wrapper_binding",
|
||||
.expr_category = ComputedExprCategory::SameAsSecondOperand});
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// A binding pattern that binds a name to the result of matching
|
||||
// `subpattern_id` against this pattern's scrutinee. Currently there is no
|
||||
// explicit syntax for such a pattern, but it arises implicitly when handling
|
||||
|
||||
Reference in New Issue
Block a user