mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Support importing var parameters (#5400)
This restructures the import and merge logic to support parameter patterns in a more scalable way. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
8e666cea3e
commit
fbc5994750
+239
-319
@@ -401,9 +401,14 @@ class ImportContext {
|
||||
// - Fill in any remaining information to complete the import of the
|
||||
// instruction. For example, when importing a class declaration, build
|
||||
// the class scope and information about the definition.
|
||||
// - Return ResolveAs/ResolveAsConstant to finish the resolution process.
|
||||
// This will cause the Resolve loop to set a constant value if we didn't
|
||||
// retry at the end of the second phase.
|
||||
// - Return Done() to finish the resolution process. This will cause the
|
||||
// Resolve loop to set a constant value if we didn't retry at the end of
|
||||
// the second phase.
|
||||
//
|
||||
// In the common case where the second phase cannot add new work (because the
|
||||
// inst doesn't represent a declaration of an entity that can be forward
|
||||
// declared), the second and third phases are usually expressed as a call to
|
||||
// ResolveAsDeduplicated or ResolveAsUnique.
|
||||
//
|
||||
// 3. If resolve didn't return Retry(), pop the work. Otherwise, it needs to
|
||||
// remain, and may no longer be at the top of the stack; update the state of
|
||||
@@ -516,6 +521,9 @@ class ImportRefResolver : public ImportContext {
|
||||
// Returns the ConstantId for an InstId. Adds unresolved constants to
|
||||
// work_stack_.
|
||||
auto GetLocalConstantValueOrPush(SemIR::InstId inst_id) -> SemIR::ConstantId {
|
||||
if (!inst_id.has_value()) {
|
||||
return SemIR::ConstantId::None;
|
||||
}
|
||||
auto const_id =
|
||||
local_constant_values_for_import_insts().GetAttached(inst_id);
|
||||
if (!const_id.has_value()) {
|
||||
@@ -654,7 +662,7 @@ static auto SetConstantValue(Context& context, SemIR::InstId inst_id,
|
||||
|
||||
// Adds an imported instruction without setting its constant value. The
|
||||
// instruction should later be updated by either `SetConstantValue` or
|
||||
// `ReplaceImportedInstAndSetConstantValue`.
|
||||
// `ReplacePlaceholderImportedInst`.
|
||||
template <typename InstT>
|
||||
static auto AddPlaceholderImportedInst(ImportContext& context,
|
||||
SemIR::InstId import_inst_id, InstT inst)
|
||||
@@ -662,33 +670,13 @@ static auto AddPlaceholderImportedInst(ImportContext& context,
|
||||
auto inst_id = context.local_insts().AddInNoBlock(MakeImportedLocIdAndInst(
|
||||
context.local_context(), AddImportIRInst(context, import_inst_id), inst));
|
||||
CARBON_VLOG_TO(context.local_context().vlog_stream(),
|
||||
"AddImportedInst: {0}\n", static_cast<SemIR::Inst>(inst));
|
||||
"AddPlaceholderImportedInst: {0}\n", inst);
|
||||
// Track the instruction in the imports block so that it's included in
|
||||
// formatted SemIR if it's referenced.
|
||||
context.local_context().import_ref_ids().push_back(inst_id);
|
||||
return inst_id;
|
||||
}
|
||||
|
||||
// Adds an imported instruction. The constant value of the instruction will be
|
||||
// computed.
|
||||
//
|
||||
// Normally `AddImportedConstant` should be used to create the result of
|
||||
// resolving a constant, for example by calling `ResolveAs*`. However, we
|
||||
// sometimes need to create a new instruction, not just obtain a constant value,
|
||||
// such as when importing a declaration or a pattern. In that case, this
|
||||
// function should be used to create it.
|
||||
//
|
||||
// Do not use `AddInst*`, as it will add symbolic constants to the eval block of
|
||||
// whatever generic the import happens within.
|
||||
template <typename InstT>
|
||||
static auto AddImportedInst(ImportContext& context,
|
||||
SemIR::InstId import_inst_id, InstT inst)
|
||||
-> SemIR::InstId {
|
||||
auto inst_id = AddPlaceholderImportedInst(context, import_inst_id, inst);
|
||||
SetConstantValue(context.local_context(), inst_id, inst);
|
||||
return inst_id;
|
||||
}
|
||||
|
||||
// Replace an imported instruction that was added by
|
||||
// `AddPlaceholderImportedInst` with a new instruction. Computes, sets, and
|
||||
// returns the new constant value.
|
||||
@@ -745,35 +733,6 @@ static auto GetLocalConstantId(ImportRefResolver& resolver,
|
||||
resolver.import_types().GetConstantId(type_id));
|
||||
}
|
||||
|
||||
// Returns the ConstantId for an InstId that is required to have already been
|
||||
// imported.
|
||||
static auto GetLocalConstantIdChecked(ImportContext& context,
|
||||
SemIR::InstId inst_id)
|
||||
-> SemIR::ConstantId {
|
||||
auto result_id =
|
||||
context.local_constant_values_for_import_insts().GetAttached(inst_id);
|
||||
CARBON_CHECK(result_id.has_value());
|
||||
return result_id;
|
||||
}
|
||||
|
||||
// Returns the ConstantId for a ConstantId that is required to have already been
|
||||
// imported.
|
||||
static auto GetLocalConstantIdChecked(ImportContext& context,
|
||||
SemIR::ConstantId const_id)
|
||||
-> SemIR::ConstantId {
|
||||
return GetLocalConstantIdChecked(
|
||||
context, GetInstWithConstantValue(context.import_ir(), const_id));
|
||||
}
|
||||
|
||||
// Returns the ConstantId for a TypeId that is required to have already been
|
||||
// imported.
|
||||
static auto GetLocalConstantIdChecked(ImportContext& context,
|
||||
SemIR::TypeId type_id)
|
||||
-> SemIR::ConstantId {
|
||||
return GetLocalConstantIdChecked(
|
||||
context, context.import_types().GetConstantId(type_id));
|
||||
}
|
||||
|
||||
// Translates a NameId from the import IR to a local NameId.
|
||||
static auto GetLocalNameId(ImportContext& context, SemIR::NameId import_name_id)
|
||||
-> SemIR::NameId {
|
||||
@@ -1039,164 +998,6 @@ static auto GetLocalSpecificInterface(
|
||||
}
|
||||
}
|
||||
|
||||
// Adds unresolved constants for each parameter's type to the resolver's work
|
||||
// stack.
|
||||
static auto LoadLocalPatternConstantIds(ImportRefResolver& resolver,
|
||||
SemIR::InstBlockId param_patterns_id)
|
||||
-> void {
|
||||
if (!param_patterns_id.has_value() ||
|
||||
param_patterns_id == SemIR::InstBlockId::Empty) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& param_patterns =
|
||||
resolver.import_inst_blocks().Get(param_patterns_id);
|
||||
for (auto pattern_id : param_patterns) {
|
||||
auto pattern_inst = resolver.import_insts().GetWithAttachedType(pattern_id);
|
||||
GetLocalConstantId(resolver, pattern_inst.type_id());
|
||||
if (auto addr = pattern_inst.TryAs<SemIR::AddrPattern>()) {
|
||||
pattern_id = addr->inner_id;
|
||||
pattern_inst = resolver.import_insts().GetWithAttachedType(pattern_id);
|
||||
GetLocalConstantId(resolver, pattern_inst.type_id());
|
||||
}
|
||||
// If the parameter is a symbolic binding, build the
|
||||
// SymbolicBindingPattern constant.
|
||||
if (pattern_inst.Is<SemIR::SymbolicBindingPattern>()) {
|
||||
GetLocalConstantId(resolver, pattern_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a version of param_patterns_id localized to the current IR.
|
||||
//
|
||||
// Must only be called after a call to
|
||||
// LoadLocalPatternConstantIds(param_patterns_id) has completed without adding
|
||||
// any new work to work_stack_.
|
||||
//
|
||||
// TODO: This is inconsistent with the rest of this class, which expects
|
||||
// the relevant constants to be explicitly passed in. That makes it
|
||||
// easier to statically detect when an input isn't loaded, but makes it
|
||||
// harder to support importing more complex inst structures. We should
|
||||
// take a holistic look at how to balance those concerns. For example,
|
||||
// could the same function be used to load the constants and use them, with
|
||||
// a parameter to select between the two?
|
||||
//
|
||||
// `self_param_id` is an optional out parameter, populated with the InstId in
|
||||
// the resulting parameter patterns that represents the Self parameter.
|
||||
static auto GetLocalParamPatternsId(ImportContext& context,
|
||||
SemIR::InstBlockId param_patterns_id,
|
||||
SemIR::InstId* self_param_id = nullptr)
|
||||
-> SemIR::InstBlockId {
|
||||
CARBON_CHECK(!self_param_id || !self_param_id->has_value());
|
||||
if (!param_patterns_id.has_value() ||
|
||||
param_patterns_id == SemIR::InstBlockId::Empty) {
|
||||
return param_patterns_id;
|
||||
}
|
||||
const auto& param_patterns =
|
||||
context.import_inst_blocks().Get(param_patterns_id);
|
||||
llvm::SmallVector<SemIR::InstId> new_patterns;
|
||||
for (auto inst_id : param_patterns) {
|
||||
// Figure out the pattern structure. This echoes
|
||||
// Function::GetParamPatternInfoFromPatternId.
|
||||
auto inst = context.import_insts().GetWithAttachedType(inst_id);
|
||||
|
||||
auto addr_pattern_id = inst_id;
|
||||
auto addr_inst = inst.TryAs<SemIR::AddrPattern>();
|
||||
if (addr_inst) {
|
||||
inst_id = addr_inst->inner_id;
|
||||
inst = context.import_insts().GetWithAttachedType(inst_id);
|
||||
}
|
||||
|
||||
auto param_pattern_id = inst_id;
|
||||
auto param_pattern = inst.TryAs<SemIR::ValueParamPattern>();
|
||||
if (param_pattern) {
|
||||
inst_id = param_pattern->subpattern_id;
|
||||
inst = context.import_insts().GetWithAttachedType(inst_id);
|
||||
}
|
||||
|
||||
auto binding_id = inst_id;
|
||||
auto binding = inst.As<SemIR::AnyBindingPattern>();
|
||||
|
||||
// Rebuild the pattern.
|
||||
auto entity_name =
|
||||
context.import_entity_names().Get(binding.entity_name_id);
|
||||
auto name_id = GetLocalNameId(context, entity_name.name_id);
|
||||
auto type_id = context.local_context().types().GetTypeIdForTypeConstantId(
|
||||
GetLocalConstantIdChecked(context, binding.type_id));
|
||||
|
||||
auto new_param_id = SemIR::InstId::None;
|
||||
switch (binding.kind) {
|
||||
case SemIR::BindingPattern::Kind: {
|
||||
auto entity_name_id = context.local_entity_names().Add(
|
||||
{.name_id = name_id, .parent_scope_id = SemIR::NameScopeId::None});
|
||||
new_param_id = AddImportedInst<SemIR::BindingPattern>(
|
||||
context, binding_id,
|
||||
{.type_id = type_id, .entity_name_id = entity_name_id});
|
||||
break;
|
||||
}
|
||||
case SemIR::SymbolicBindingPattern::Kind: {
|
||||
// We already imported a constant value for this symbolic binding.
|
||||
// We can reuse most of it, but update the value to point to our
|
||||
// specific parameter, and preserve the constant value.
|
||||
auto bind_const_id = GetLocalConstantIdChecked(context, binding_id);
|
||||
auto new_binding_inst =
|
||||
context.local_insts().GetAs<SemIR::SymbolicBindingPattern>(
|
||||
context.local_constant_values().GetInstId(bind_const_id));
|
||||
new_param_id = AddImportedInst(context, binding_id, new_binding_inst);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
CARBON_FATAL("Unexpected kind: ", binding.kind);
|
||||
}
|
||||
}
|
||||
if (param_pattern) {
|
||||
new_param_id = AddImportedInst<SemIR::ValueParamPattern>(
|
||||
context, param_pattern_id,
|
||||
{.type_id = type_id,
|
||||
.subpattern_id = new_param_id,
|
||||
.index = param_pattern->index});
|
||||
}
|
||||
if (addr_inst) {
|
||||
type_id = context.local_context().types().GetTypeIdForTypeConstantId(
|
||||
GetLocalConstantIdChecked(context, addr_inst->type_id));
|
||||
new_param_id = AddImportedInst<SemIR::AddrPattern>(
|
||||
context, addr_pattern_id,
|
||||
{.type_id = type_id, .inner_id = new_param_id});
|
||||
}
|
||||
if (self_param_id &&
|
||||
context.import_entity_names().Get(binding.entity_name_id).name_id ==
|
||||
SemIR::NameId::SelfValue) {
|
||||
*self_param_id = new_param_id;
|
||||
}
|
||||
new_patterns.push_back(new_param_id);
|
||||
}
|
||||
return context.local_inst_blocks().Add(new_patterns);
|
||||
}
|
||||
|
||||
// Returns a version of import_return_slot_pattern_id localized to the current
|
||||
// IR.
|
||||
static auto GetLocalReturnSlotPatternId(
|
||||
ImportContext& context, SemIR::InstId import_return_slot_pattern_id,
|
||||
SemIR::ConstantId return_type_const_id) -> SemIR::InstId {
|
||||
if (!import_return_slot_pattern_id.has_value()) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
|
||||
auto param_pattern = context.import_insts().GetAs<SemIR::OutParamPattern>(
|
||||
import_return_slot_pattern_id);
|
||||
auto type_id = context.local_context().types().GetTypeIdForTypeConstantId(
|
||||
return_type_const_id);
|
||||
|
||||
auto new_return_slot_pattern_id = AddImportedInst<SemIR::ReturnSlotPattern>(
|
||||
context, param_pattern.subpattern_id,
|
||||
{.type_id = type_id, .type_inst_id = SemIR::TypeInstId::None});
|
||||
return AddImportedInst<SemIR::OutParamPattern>(
|
||||
context, import_return_slot_pattern_id,
|
||||
{.type_id = type_id,
|
||||
.subpattern_id = new_return_slot_pattern_id,
|
||||
.index = param_pattern.index});
|
||||
}
|
||||
|
||||
// Translates a NameScopeId from the import IR to a local NameScopeId. Adds
|
||||
// unresolved constants to the resolver's work stack.
|
||||
static auto GetLocalNameScopeId(ImportRefResolver& resolver,
|
||||
@@ -1395,26 +1196,55 @@ static auto RetryOrDone(ImportRefResolver& resolver, SemIR::ConstantId const_id)
|
||||
return ResolveResult::Done(const_id);
|
||||
}
|
||||
|
||||
// Produces a resolve result for the given instruction that describes a constant
|
||||
// value. This should only be used for instructions that describe constants, and
|
||||
// not for instructions that represent declarations. For a declaration, we need
|
||||
// an associated location, so AddImportedInst should be used instead. Requires
|
||||
// that there is no new work.
|
||||
static auto ResolveAsUntyped(ImportContext& context, SemIR::Inst inst)
|
||||
// Adds `inst` to the local context as a deduplicated constant and returns a
|
||||
// successful `ResolveResult`. Requires that there is no new work.
|
||||
//
|
||||
// This implements phases 2 and 3 of resolving the inst (as described above) for
|
||||
// the common case where those phases are combined. Cases where that isn't
|
||||
// applicable should instead use `AddPlaceholderImportedInst` and
|
||||
// `ReplacePlaceholderImportedInst`.
|
||||
//
|
||||
// This should not be used for instructions that represent declarations, or
|
||||
// other instructions with `constant_kind == InstConstantKind::Unique`, because
|
||||
// they should not be deduplicated.
|
||||
template <typename InstT>
|
||||
static auto ResolveAsDeduplicated(ImportRefResolver& resolver, InstT inst)
|
||||
-> ResolveResult {
|
||||
static_assert(InstT::Kind.constant_kind() != SemIR::InstConstantKind::Unique,
|
||||
"Use ResolveAsUnique");
|
||||
CARBON_CHECK(!resolver.HasNewWork());
|
||||
// AddImportedConstant produces an unattached constant, so its type must
|
||||
// be unattached as well.
|
||||
inst.SetType(
|
||||
context.local_context().types().GetUnattachedType(inst.type_id()));
|
||||
auto result = AddImportedConstant(context.local_context(), inst);
|
||||
CARBON_CHECK(result.is_constant(), "{0} is not constant", inst);
|
||||
return ResolveResult::Done(result);
|
||||
inst.type_id =
|
||||
resolver.local_context().types().GetUnattachedType(inst.type_id);
|
||||
auto const_id = AddImportedConstant(resolver.local_context(), inst);
|
||||
CARBON_CHECK(const_id.is_constant(), "{0} is not constant", inst);
|
||||
return ResolveResult::Done(const_id);
|
||||
}
|
||||
|
||||
// Same as ResolveAsUntyped, but with an explicit type for convenience.
|
||||
// Adds `inst` to the local context as a unique constant and returns a
|
||||
// successful `ResolveResult`. `import_inst_id` is the corresponding inst ID in
|
||||
// the local context. Requires that there is no new work.
|
||||
//
|
||||
// This implements phases 2 and 3 of resolving the inst (as described above) for
|
||||
// the common case where those phases are combined. Cases where that isn't
|
||||
// applicable should instead use `AddPlaceholderImportedInst` and
|
||||
// `ReplacePlaceholderImportedInst`.
|
||||
//
|
||||
// This should only be used for instructions that represent declarations, or
|
||||
// other instructions with `constant_kind == InstConstantKind::Unique`, because
|
||||
// it does not perform deduplication.
|
||||
template <typename InstT>
|
||||
static auto ResolveAs(ImportContext& context, InstT inst) -> ResolveResult {
|
||||
return ResolveAsUntyped(context, inst);
|
||||
static auto ResolveAsUnique(ImportRefResolver& resolver,
|
||||
SemIR::InstId import_inst_id, InstT inst)
|
||||
-> ResolveResult {
|
||||
static_assert(InstT::Kind.constant_kind() == SemIR::InstConstantKind::Unique,
|
||||
"Use ResolveAsDeduplicated");
|
||||
CARBON_CHECK(!resolver.HasNewWork());
|
||||
auto inst_id = AddPlaceholderImportedInst(resolver, import_inst_id, inst);
|
||||
auto const_id = SetConstantValue(resolver.local_context(), inst_id, inst);
|
||||
CARBON_CHECK(const_id.is_constant(), "{0} is not constant", inst);
|
||||
return ResolveResult::Done(const_id, inst_id);
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
@@ -1432,10 +1262,43 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
inst.adapted_type_inst_id, adapted_type_const_id));
|
||||
|
||||
// Create a corresponding instruction to represent the declaration.
|
||||
auto inst_id = AddImportedInst<SemIR::AdaptDecl>(
|
||||
return ResolveAsUnique<SemIR::AdaptDecl>(
|
||||
resolver, import_inst_id, {.adapted_type_inst_id = adapted_type_inst_id});
|
||||
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id),
|
||||
inst_id);
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::AddrPattern inst,
|
||||
SemIR::InstId import_inst_id) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
auto inner_id = GetLocalConstantInstId(resolver, inst.inner_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAsUnique<SemIR::AddrPattern>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.inner_id = inner_id});
|
||||
}
|
||||
|
||||
template <typename ParamPatternT>
|
||||
requires SemIR::Internal::HasInstCategory<SemIR::AnyParamPattern,
|
||||
ParamPatternT>
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver, ParamPatternT inst,
|
||||
SemIR::InstId import_inst_id) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
auto subpattern_id = GetLocalConstantInstId(resolver, inst.subpattern_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAsUnique<ParamPatternT>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.subpattern_id = subpattern_id,
|
||||
.index = inst.index});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
@@ -1448,7 +1311,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::ArrayType>(
|
||||
return ResolveAsDeduplicated<SemIR::ArrayType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.bound_id = bound_id,
|
||||
.element_type_inst_id = element_type_inst_id});
|
||||
@@ -1541,7 +1404,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
// Add a lazy reference to the target declaration.
|
||||
auto decl_id = AddImportRef(resolver, inst.decl_id);
|
||||
|
||||
return ResolveAs<SemIR::AssociatedEntity>(
|
||||
return ResolveAsDeduplicated<SemIR::AssociatedEntity>(
|
||||
resolver,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
@@ -1562,7 +1425,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
|
||||
auto specific_interface =
|
||||
GetLocalSpecificInterface(resolver, inst.GetSpecificInterface(), data);
|
||||
return ResolveAs<SemIR::AssociatedEntityType>(
|
||||
return ResolveAsDeduplicated<SemIR::AssociatedEntityType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.interface_id = specific_interface.interface_id,
|
||||
.interface_specific_id = specific_interface.specific_id});
|
||||
@@ -1584,14 +1447,12 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
inst.base_type_inst_id, base_type_const_id));
|
||||
|
||||
// Create a corresponding instruction to represent the declaration.
|
||||
auto inst_id = AddImportedInst<SemIR::BaseDecl>(
|
||||
return ResolveAsUnique<SemIR::BaseDecl>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.base_type_inst_id = base_type_inst_id,
|
||||
.index = inst.index});
|
||||
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id),
|
||||
inst_id);
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Vtable inst)
|
||||
@@ -1605,7 +1466,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Vtable inst)
|
||||
|
||||
auto virtual_functions_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, inst.virtual_functions_id, virtual_functions);
|
||||
return ResolveAs<SemIR::Vtable>(
|
||||
return ResolveAsDeduplicated<SemIR::Vtable>(
|
||||
resolver,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
@@ -1628,12 +1489,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
const auto& import_entity_name =
|
||||
resolver.import_entity_names().Get(inst.entity_name_id);
|
||||
auto name_id = GetLocalNameId(resolver, import_entity_name.name_id);
|
||||
// TODO: Use the same `EntityName` for the `SymbolicBindingPattern` and the
|
||||
// `BindSymbolicName`.
|
||||
auto entity_name_id = resolver.local_entity_names().AddSymbolicBindingName(
|
||||
name_id, SemIR::NameScopeId::None, import_entity_name.bind_index(),
|
||||
import_entity_name.is_template);
|
||||
return ResolveAs<SemIR::BindSymbolicName>(
|
||||
return ResolveAsDeduplicated<SemIR::BindSymbolicName>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -1641,10 +1500,13 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
.value_id = SemIR::InstId::None});
|
||||
}
|
||||
|
||||
template <typename BindingPatternT>
|
||||
requires SemIR::Internal::HasInstCategory<SemIR::AnyBindingPattern,
|
||||
BindingPatternT>
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::SymbolicBindingPattern inst)
|
||||
-> ResolveResult {
|
||||
auto type_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
BindingPatternT inst,
|
||||
SemIR::InstId import_inst_id) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
@@ -1652,15 +1514,15 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
const auto& import_entity_name =
|
||||
resolver.import_entity_names().Get(inst.entity_name_id);
|
||||
auto name_id = GetLocalNameId(resolver, import_entity_name.name_id);
|
||||
// TODO: Use the same `EntityName` for the `SymbolicBindingPattern` and the
|
||||
// `BindSymbolicName`.
|
||||
auto entity_name_id = resolver.local_entity_names().AddSymbolicBindingName(
|
||||
name_id, SemIR::NameScopeId::None, import_entity_name.bind_index(),
|
||||
import_entity_name.is_template);
|
||||
return ResolveAs<SemIR::SymbolicBindingPattern>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
auto entity_name_id = resolver.local_entity_names().Add(
|
||||
{.name_id = name_id,
|
||||
.parent_scope_id = SemIR::NameScopeId::None,
|
||||
.bind_index_value = import_entity_name.bind_index().index,
|
||||
.is_template = import_entity_name.is_template});
|
||||
return ResolveAsUnique<BindingPatternT>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.entity_name_id = entity_name_id});
|
||||
}
|
||||
|
||||
@@ -1676,7 +1538,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::BoundMethod>(
|
||||
return ResolveAsDeduplicated<SemIR::BoundMethod>(
|
||||
resolver,
|
||||
{.type_id = GetSingletonType(resolver.local_context(),
|
||||
SemIR::BoundMethodType::TypeInstId),
|
||||
@@ -1694,7 +1556,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Call inst)
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::Call>(
|
||||
return ResolveAsDeduplicated<SemIR::Call>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -1815,9 +1677,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
// Load constants for the definition.
|
||||
auto parent_scope_id =
|
||||
GetLocalNameScopeId(resolver, import_class.parent_scope_id);
|
||||
LoadLocalPatternConstantIds(resolver,
|
||||
import_class.implicit_param_patterns_id);
|
||||
LoadLocalPatternConstantIds(resolver, import_class.param_patterns_id);
|
||||
auto implicit_param_patterns = GetLocalInstBlockContents(
|
||||
resolver, import_class.implicit_param_patterns_id);
|
||||
auto param_patterns =
|
||||
GetLocalInstBlockContents(resolver, import_class.param_patterns_id);
|
||||
auto generic_data = GetLocalGenericData(resolver, import_class.generic_id);
|
||||
auto self_const_id = GetLocalConstantId(resolver, import_class.self_type_id);
|
||||
auto complete_type_witness_const_id =
|
||||
@@ -1841,10 +1704,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
: SemIR::InstId::None;
|
||||
|
||||
new_class.parent_scope_id = parent_scope_id;
|
||||
new_class.implicit_param_patterns_id = GetLocalParamPatternsId(
|
||||
resolver, import_class.implicit_param_patterns_id);
|
||||
new_class.param_patterns_id =
|
||||
GetLocalParamPatternsId(resolver, import_class.param_patterns_id);
|
||||
new_class.implicit_param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_class.implicit_param_patterns_id,
|
||||
implicit_param_patterns);
|
||||
new_class.param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_class.param_patterns_id, param_patterns);
|
||||
SetGenericData(resolver, import_class.generic_id, new_class.generic_id,
|
||||
generic_data);
|
||||
new_class.self_type_id =
|
||||
@@ -1888,10 +1752,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
class_const_inst.type_id());
|
||||
auto specific_id =
|
||||
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);
|
||||
return ResolveAs<SemIR::ClassType>(resolver,
|
||||
{.type_id = SemIR::TypeType::TypeId,
|
||||
.class_id = generic_class_type.class_id,
|
||||
.specific_id = specific_id});
|
||||
return ResolveAsDeduplicated<SemIR::ClassType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.class_id = generic_class_type.class_id,
|
||||
.specific_id = specific_id});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1905,7 +1769,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
return ResolveAs<SemIR::CompleteTypeWitness>(
|
||||
return ResolveAsDeduplicated<SemIR::CompleteTypeWitness>(
|
||||
resolver, {.type_id = GetSingletonType(resolver.local_context(),
|
||||
SemIR::WitnessType::TypeInstId),
|
||||
.object_repr_type_inst_id = object_repr_type_inst_id});
|
||||
@@ -1918,7 +1782,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
return ResolveAs<SemIR::ConstType>(
|
||||
return ResolveAsDeduplicated<SemIR::ConstType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId, .inner_id = inner_id});
|
||||
}
|
||||
|
||||
@@ -1935,14 +1799,12 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
auto inst_id = AddImportedInst<SemIR::FieldDecl>(
|
||||
return ResolveAsUnique<SemIR::FieldDecl>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
const_id),
|
||||
.name_id = GetLocalNameId(resolver, inst.name_id),
|
||||
.index = inst.index});
|
||||
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id),
|
||||
inst_id);
|
||||
}
|
||||
|
||||
// Make a declaration of a function. This is done as a separate step from
|
||||
@@ -2017,12 +1879,17 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
}
|
||||
auto parent_scope_id =
|
||||
GetLocalNameScopeId(resolver, import_function.parent_scope_id);
|
||||
LoadLocalPatternConstantIds(resolver,
|
||||
import_function.implicit_param_patterns_id);
|
||||
LoadLocalPatternConstantIds(resolver, import_function.param_patterns_id);
|
||||
auto implicit_param_patterns = GetLocalInstBlockContents(
|
||||
resolver, import_function.implicit_param_patterns_id);
|
||||
auto param_patterns =
|
||||
GetLocalInstBlockContents(resolver, import_function.param_patterns_id);
|
||||
auto generic_data = GetLocalGenericData(resolver, import_function.generic_id);
|
||||
auto& new_function = resolver.local_functions().Get(function_id);
|
||||
auto self_param_id =
|
||||
GetLocalConstantInstId(resolver, import_function.self_param_id);
|
||||
auto return_slot_pattern_id =
|
||||
GetLocalConstantInstId(resolver, import_function.return_slot_pattern_id);
|
||||
|
||||
auto& new_function = resolver.local_functions().Get(function_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry(function_const_id,
|
||||
new_function.first_decl_id());
|
||||
@@ -2030,14 +1897,13 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
|
||||
// Add the function declaration.
|
||||
new_function.parent_scope_id = parent_scope_id;
|
||||
SemIR::InstId self_param_id = SemIR::InstId::None;
|
||||
new_function.implicit_param_patterns_id = GetLocalParamPatternsId(
|
||||
resolver, import_function.implicit_param_patterns_id, &self_param_id);
|
||||
new_function.implicit_param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_function.implicit_param_patterns_id,
|
||||
implicit_param_patterns);
|
||||
new_function.self_param_id = self_param_id;
|
||||
new_function.param_patterns_id =
|
||||
GetLocalParamPatternsId(resolver, import_function.param_patterns_id);
|
||||
new_function.return_slot_pattern_id = GetLocalReturnSlotPatternId(
|
||||
resolver, import_function.return_slot_pattern_id, return_type_const_id);
|
||||
new_function.param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_function.param_patterns_id, param_patterns);
|
||||
new_function.return_slot_pattern_id = return_slot_pattern_id;
|
||||
SetGenericData(resolver, import_function.generic_id, new_function.generic_id,
|
||||
generic_data);
|
||||
|
||||
@@ -2059,7 +1925,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
auto fn_type_id = resolver.local_insts().Get(fn_val_id).type_id();
|
||||
return ResolveAs<SemIR::FunctionType>(
|
||||
return ResolveAsDeduplicated<SemIR::FunctionType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.function_id = resolver.local_types()
|
||||
.GetAs<SemIR::FunctionType>(fn_type_id)
|
||||
@@ -2079,7 +1945,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::FunctionTypeWithSelfType>(
|
||||
return ResolveAsDeduplicated<SemIR::FunctionTypeWithSelfType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.interface_function_type_id = interface_function_type_id,
|
||||
.self_id = self_id});
|
||||
@@ -2206,7 +2072,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
// Load constants for the definition.
|
||||
auto parent_scope_id =
|
||||
GetLocalNameScopeId(resolver, import_impl.parent_scope_id);
|
||||
LoadLocalPatternConstantIds(resolver, import_impl.implicit_param_patterns_id);
|
||||
auto implicit_param_patterns = GetLocalInstBlockContents(
|
||||
resolver, import_impl.implicit_param_patterns_id);
|
||||
auto generic_data = GetLocalGenericData(resolver, import_impl.generic_id);
|
||||
auto self_const_id = GetLocalConstantId(
|
||||
resolver,
|
||||
@@ -2221,8 +2088,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
}
|
||||
|
||||
new_impl.parent_scope_id = parent_scope_id;
|
||||
new_impl.implicit_param_patterns_id =
|
||||
GetLocalParamPatternsId(resolver, import_impl.implicit_param_patterns_id);
|
||||
new_impl.implicit_param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_impl.implicit_param_patterns_id,
|
||||
implicit_param_patterns);
|
||||
SetGenericData(resolver, import_impl.generic_id, new_impl.generic_id,
|
||||
generic_data);
|
||||
|
||||
@@ -2374,9 +2242,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
|
||||
auto parent_scope_id =
|
||||
GetLocalNameScopeId(resolver, import_interface.parent_scope_id);
|
||||
LoadLocalPatternConstantIds(resolver,
|
||||
import_interface.implicit_param_patterns_id);
|
||||
LoadLocalPatternConstantIds(resolver, import_interface.param_patterns_id);
|
||||
auto implicit_param_patterns = GetLocalInstBlockContents(
|
||||
resolver, import_interface.implicit_param_patterns_id);
|
||||
auto param_patterns =
|
||||
GetLocalInstBlockContents(resolver, import_interface.param_patterns_id);
|
||||
auto generic_data =
|
||||
GetLocalGenericData(resolver, import_interface.generic_id);
|
||||
|
||||
@@ -2393,10 +2262,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
}
|
||||
|
||||
new_interface.parent_scope_id = parent_scope_id;
|
||||
new_interface.implicit_param_patterns_id = GetLocalParamPatternsId(
|
||||
resolver, import_interface.implicit_param_patterns_id);
|
||||
new_interface.param_patterns_id =
|
||||
GetLocalParamPatternsId(resolver, import_interface.param_patterns_id);
|
||||
new_interface.implicit_param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_interface.implicit_param_patterns_id,
|
||||
implicit_param_patterns);
|
||||
new_interface.param_patterns_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_interface.param_patterns_id, param_patterns);
|
||||
SetGenericData(resolver, import_interface.generic_id,
|
||||
new_interface.generic_id, generic_data);
|
||||
|
||||
@@ -2416,7 +2286,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::FacetAccessType>(
|
||||
return ResolveAsDeduplicated<SemIR::FacetAccessType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.facet_value_inst_id = facet_value_inst_id});
|
||||
}
|
||||
@@ -2471,7 +2341,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
// TODO: Also process the other requirements.
|
||||
SemIR::FacetTypeId facet_type_id =
|
||||
resolver.local_facet_types().Add(std::move(local_facet_type_info));
|
||||
return ResolveAs<SemIR::FacetType>(
|
||||
return ResolveAsDeduplicated<SemIR::FacetType>(
|
||||
resolver,
|
||||
{.type_id = SemIR::TypeType::TypeId, .facet_type_id = facet_type_id});
|
||||
}
|
||||
@@ -2485,7 +2355,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::FacetValue>(
|
||||
return ResolveAsDeduplicated<SemIR::FacetValue>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -2517,7 +2387,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
GetLocalSpecificInterface(resolver, import_specific_interface, data);
|
||||
auto query_specific_interface_id =
|
||||
resolver.local_specific_interfaces().Add(specific_interface);
|
||||
return ResolveAs<SemIR::LookupImplWitness>(
|
||||
return ResolveAsDeduplicated<SemIR::LookupImplWitness>(
|
||||
resolver, {.type_id = GetSingletonType(resolver.local_context(),
|
||||
SemIR::WitnessType::TypeInstId),
|
||||
.query_self_inst_id = query_self_inst_id,
|
||||
@@ -2538,7 +2408,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
|
||||
auto specific_id =
|
||||
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);
|
||||
return ResolveAs<SemIR::ImplWitness>(
|
||||
return ResolveAsDeduplicated<SemIR::ImplWitness>(
|
||||
resolver, {.type_id = GetSingletonType(resolver.local_context(),
|
||||
SemIR::WitnessType::TypeInstId),
|
||||
.witness_table_id = witness_table_id,
|
||||
@@ -2554,7 +2424,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::ImplWitnessAccess>(
|
||||
return ResolveAsDeduplicated<SemIR::ImplWitnessAccess>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -2579,11 +2449,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
auto elements_id = GetLocalImportRefInstBlock(resolver, inst.elements_id);
|
||||
|
||||
// Create a corresponding instruction to represent the table.
|
||||
auto inst_id = AddImportedInst<SemIR::ImplWitnessTable>(
|
||||
return ResolveAsUnique<SemIR::ImplWitnessTable>(
|
||||
resolver, import_inst_id,
|
||||
{.elements_id = elements_id, .impl_id = impl_id});
|
||||
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id),
|
||||
inst_id);
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
@@ -2600,7 +2468,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
: resolver.local_ints().AddSigned(
|
||||
resolver.import_ints().Get(inst.int_id));
|
||||
|
||||
return ResolveAs<SemIR::IntValue>(
|
||||
return ResolveAsDeduplicated<SemIR::IntValue>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -2615,10 +2483,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::IntType>(resolver,
|
||||
{.type_id = SemIR::TypeType::TypeId,
|
||||
.int_kind = inst.int_kind,
|
||||
.bit_width_id = bit_width_id});
|
||||
return ResolveAsDeduplicated<SemIR::IntType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.int_kind = inst.int_kind,
|
||||
.bit_width_id = bit_width_id});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
@@ -2668,7 +2536,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::PatternType>(
|
||||
return ResolveAsDeduplicated<SemIR::PatternType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.scrutinee_type_inst_id = scrutinee_type_inst_id});
|
||||
}
|
||||
@@ -2681,7 +2549,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::PointerType>(
|
||||
return ResolveAsDeduplicated<SemIR::PointerType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId, .pointee_id = pointee_id});
|
||||
}
|
||||
|
||||
@@ -2697,12 +2565,27 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::RequireCompleteType>(
|
||||
return ResolveAsDeduplicated<SemIR::RequireCompleteType>(
|
||||
resolver, {.type_id = GetSingletonType(resolver.local_context(),
|
||||
SemIR::WitnessType::TypeInstId),
|
||||
.complete_type_inst_id = complete_type_inst_id});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::ReturnSlotPattern inst,
|
||||
SemIR::InstId import_inst_id) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAsUnique<SemIR::ReturnSlotPattern>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.type_inst_id = SemIR::TypeInstId::None});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::SpecificFunction inst) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
@@ -2716,7 +2599,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
type_const_id);
|
||||
auto specific_id =
|
||||
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);
|
||||
return ResolveAs<SemIR::SpecificFunction>(
|
||||
return ResolveAsDeduplicated<SemIR::SpecificFunction>(
|
||||
resolver,
|
||||
{.type_id = type_id, .callee_id = callee_id, .specific_id = specific_id});
|
||||
}
|
||||
@@ -2734,7 +2617,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::SpecificFunctionType::TypeInstId);
|
||||
auto specific_id =
|
||||
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);
|
||||
return ResolveAs<SemIR::SpecificImplFunction>(
|
||||
return ResolveAsDeduplicated<SemIR::SpecificImplFunction>(
|
||||
resolver,
|
||||
{.type_id = type_id, .callee_id = callee_id, .specific_id = specific_id});
|
||||
}
|
||||
@@ -2763,7 +2646,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
{.name_id = name_id, .type_inst_id = field_type_inst_id});
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::StructType>(
|
||||
return ResolveAsDeduplicated<SemIR::StructType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.fields_id = resolver.local_struct_type_fields().AddCanonical(
|
||||
new_fields)});
|
||||
@@ -2777,7 +2660,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::StructValue>(
|
||||
return ResolveAsDeduplicated<SemIR::StructValue>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -2803,7 +2686,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::TupleType>(
|
||||
return ResolveAsDeduplicated<SemIR::TupleType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.type_elements_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, inst.type_elements_id, type_inst_ids)});
|
||||
@@ -2817,7 +2700,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::TupleValue>(
|
||||
return ResolveAsDeduplicated<SemIR::TupleValue>(
|
||||
resolver,
|
||||
{.type_id =
|
||||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id),
|
||||
@@ -2837,12 +2720,28 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::UnboundElementType>(
|
||||
return ResolveAsDeduplicated<SemIR::UnboundElementType>(
|
||||
resolver, {.type_id = SemIR::TypeType::TypeId,
|
||||
.class_type_inst_id = class_const_inst_id,
|
||||
.element_type_inst_id = elem_const_inst_id});
|
||||
}
|
||||
|
||||
static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
||||
SemIR::VarPattern inst,
|
||||
SemIR::InstId import_inst_id) -> ResolveResult {
|
||||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id);
|
||||
auto subpattern_id = GetLocalConstantInstId(resolver, inst.subpattern_id);
|
||||
if (resolver.HasNewWork()) {
|
||||
return ResolveResult::Retry();
|
||||
}
|
||||
|
||||
return ResolveAsUnique<SemIR::VarPattern>(
|
||||
resolver, import_inst_id,
|
||||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId(
|
||||
type_const_id),
|
||||
.subpattern_id = subpattern_id});
|
||||
}
|
||||
|
||||
// Tries to resolve the InstId, returning a canonical constant when ready, or
|
||||
// `None` if more has been added to the stack. This is the same as
|
||||
// TryResolveInst, except that it may resolve symbolic constants as canonical
|
||||
@@ -2866,6 +2765,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
|
||||
case CARBON_KIND(SemIR::AdaptDecl inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::AddrPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::ArrayType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
@@ -2884,6 +2786,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
|
||||
case CARBON_KIND(SemIR::BindAlias inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::BindingPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case SemIR::BindName::Kind: {
|
||||
// TODO: Should we be resolving BindNames at all?
|
||||
return ResolveResult::Done(SemIR::ConstantId::NotConstant);
|
||||
@@ -2969,30 +2874,39 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
|
||||
case CARBON_KIND(SemIR::Namespace inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::OutParamPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::PatternType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::PointerType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::RefParamPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::RequireCompleteType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::ReturnSlotPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::SpecificFunction inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::SpecificImplFunction inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::SymbolicBindingPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::StructType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::StructValue inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::SymbolicBindingPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::TupleType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
@@ -3002,6 +2916,12 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
|
||||
case CARBON_KIND(SemIR::UnboundElementType inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::ValueParamPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::VarPattern inst): {
|
||||
return TryResolveTypedInst(resolver, inst, inst_id);
|
||||
}
|
||||
case CARBON_KIND(SemIR::Vtable inst): {
|
||||
return TryResolveTypedInst(resolver, inst);
|
||||
}
|
||||
|
||||
+90
-70
@@ -203,13 +203,10 @@ static auto EntityHasParamError(Context& context, const DeclParams& info)
|
||||
// to provide a diagnostic.
|
||||
static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
int32_t param_index,
|
||||
SemIR::InstId new_param_pattern_id,
|
||||
SemIR::InstId prev_param_pattern_id,
|
||||
SemIR::InstId orig_new_param_pattern_id,
|
||||
SemIR::InstId orig_prev_param_pattern_id,
|
||||
SemIR::SpecificId prev_specific_id, bool diagnose,
|
||||
bool check_syntax, bool check_self) -> bool {
|
||||
auto orig_new_param_pattern_id = new_param_pattern_id;
|
||||
auto orig_prev_param_pattern_id = prev_param_pattern_id;
|
||||
|
||||
// TODO: Consider differentiating between type and name mistakes. For now,
|
||||
// taking the simpler approach because I also think we may want to refactor
|
||||
// params.
|
||||
@@ -232,78 +229,101 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
.Emit();
|
||||
};
|
||||
|
||||
auto new_param_pattern = context.insts().Get(new_param_pattern_id);
|
||||
auto prev_param_pattern = context.insts().Get(prev_param_pattern_id);
|
||||
if (new_param_pattern.kind() != prev_param_pattern.kind()) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
}
|
||||
struct PatternPair {
|
||||
SemIR::InstId prev_id;
|
||||
SemIR::InstId new_id;
|
||||
};
|
||||
|
||||
if (new_param_pattern.Is<SemIR::AddrPattern>()) {
|
||||
new_param_pattern_id = new_param_pattern.As<SemIR::AddrPattern>().inner_id;
|
||||
new_param_pattern = context.insts().Get(new_param_pattern_id);
|
||||
prev_param_pattern_id =
|
||||
prev_param_pattern.As<SemIR::AddrPattern>().inner_id;
|
||||
prev_param_pattern = context.insts().Get(prev_param_pattern_id);
|
||||
llvm::SmallVector<PatternPair, 1> pattern_stack;
|
||||
|
||||
pattern_stack.push_back({.prev_id = orig_prev_param_pattern_id,
|
||||
.new_id = orig_new_param_pattern_id});
|
||||
|
||||
do {
|
||||
auto patterns = pattern_stack.pop_back_val();
|
||||
auto new_param_pattern = context.insts().Get(patterns.new_id);
|
||||
auto prev_param_pattern = context.insts().Get(patterns.prev_id);
|
||||
if (new_param_pattern.kind() != prev_param_pattern.kind()) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_param_pattern.Is<SemIR::AnyParamPattern>()) {
|
||||
new_param_pattern_id =
|
||||
new_param_pattern.As<SemIR::ValueParamPattern>().subpattern_id;
|
||||
new_param_pattern = context.insts().Get(new_param_pattern_id);
|
||||
prev_param_pattern_id =
|
||||
prev_param_pattern.As<SemIR::ValueParamPattern>().subpattern_id;
|
||||
prev_param_pattern = context.insts().Get(prev_param_pattern_id);
|
||||
if (new_param_pattern.kind() != prev_param_pattern.kind()) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
switch (new_param_pattern.kind()) {
|
||||
case SemIR::AddrPattern::Kind: {
|
||||
pattern_stack.push_back(
|
||||
{.prev_id = prev_param_pattern.As<SemIR::AddrPattern>().inner_id,
|
||||
.new_id = new_param_pattern.As<SemIR::AddrPattern>().inner_id});
|
||||
break;
|
||||
}
|
||||
case SemIR::OutParamPattern::Kind:
|
||||
case SemIR::RefParamPattern::Kind:
|
||||
case SemIR::ValueParamPattern::Kind: {
|
||||
pattern_stack.push_back(
|
||||
{.prev_id =
|
||||
prev_param_pattern.As<SemIR::AnyParamPattern>().subpattern_id,
|
||||
.new_id =
|
||||
new_param_pattern.As<SemIR::AnyParamPattern>().subpattern_id});
|
||||
break;
|
||||
}
|
||||
case SemIR::VarPattern::Kind:
|
||||
pattern_stack.push_back(
|
||||
{.prev_id =
|
||||
prev_param_pattern.As<SemIR::VarPattern>().subpattern_id,
|
||||
.new_id =
|
||||
new_param_pattern.As<SemIR::VarPattern>().subpattern_id});
|
||||
break;
|
||||
case SemIR::BindingPattern::Kind:
|
||||
case SemIR::SymbolicBindingPattern::Kind: {
|
||||
auto new_name_id =
|
||||
context.entity_names()
|
||||
.Get(new_param_pattern.As<SemIR::AnyBindingPattern>()
|
||||
.entity_name_id)
|
||||
.name_id;
|
||||
auto prev_name_id =
|
||||
context.entity_names()
|
||||
.Get(prev_param_pattern.As<SemIR::AnyBindingPattern>()
|
||||
.entity_name_id)
|
||||
.name_id;
|
||||
|
||||
if (!check_self && new_name_id == SemIR::NameId::SelfValue &&
|
||||
prev_name_id == SemIR::NameId::SelfValue) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto prev_param_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
context.sem_ir(), prev_specific_id, patterns.prev_id);
|
||||
if (!context.types().AreEqualAcrossDeclarations(
|
||||
new_param_pattern.type_id(), prev_param_type_id)) {
|
||||
if (!diagnose) {
|
||||
return false;
|
||||
}
|
||||
CARBON_DIAGNOSTIC(
|
||||
RedeclParamDiffersType, Error,
|
||||
"type {3} of {0:implicit |}parameter {1} in "
|
||||
"redeclaration differs from previous parameter type {2}",
|
||||
Diagnostics::BoolAsSelect, int32_t, SemIR::TypeId, SemIR::TypeId);
|
||||
context.emitter()
|
||||
.Build(orig_new_param_pattern_id, RedeclParamDiffersType,
|
||||
is_implicit_param, param_index + 1, prev_param_type_id,
|
||||
new_param_pattern.type_id())
|
||||
.Note(orig_prev_param_pattern_id, RedeclParamPrevious,
|
||||
is_implicit_param)
|
||||
.Emit();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check_syntax && new_name_id != prev_name_id) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
CARBON_FATAL("Unexpected inst kind in parameter pattern: {0}",
|
||||
new_param_pattern.kind());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto new_name_id =
|
||||
context.entity_names()
|
||||
.Get(new_param_pattern.As<SemIR::AnyBindingPattern>().entity_name_id)
|
||||
.name_id;
|
||||
auto prev_name_id =
|
||||
context.entity_names()
|
||||
.Get(prev_param_pattern.As<SemIR::AnyBindingPattern>().entity_name_id)
|
||||
.name_id;
|
||||
|
||||
if (!check_self && new_name_id == SemIR::NameId::SelfValue &&
|
||||
prev_name_id == SemIR::NameId::SelfValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto prev_param_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
context.sem_ir(), prev_specific_id, prev_param_pattern_id);
|
||||
if (!context.types().AreEqualAcrossDeclarations(new_param_pattern.type_id(),
|
||||
prev_param_type_id)) {
|
||||
if (!diagnose) {
|
||||
return false;
|
||||
}
|
||||
CARBON_DIAGNOSTIC(RedeclParamDiffersType, Error,
|
||||
"type {3} of {0:implicit |}parameter {1} in "
|
||||
"redeclaration differs from previous parameter type {2}",
|
||||
Diagnostics::BoolAsSelect, int32_t, SemIR::TypeId,
|
||||
SemIR::TypeId);
|
||||
context.emitter()
|
||||
.Build(orig_new_param_pattern_id, RedeclParamDiffersType,
|
||||
is_implicit_param, param_index + 1, prev_param_type_id,
|
||||
new_param_pattern.type_id())
|
||||
.Note(orig_prev_param_pattern_id, RedeclParamPrevious,
|
||||
is_implicit_param)
|
||||
.Emit();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check_syntax && new_name_id != prev_name_id) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
}
|
||||
} while (!pattern_stack.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ var dyn: Float(dyn_size);
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Float.type: type = fn_type @Float [concrete]
|
||||
// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [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: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.501: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete]
|
||||
// CHECK:STDOUT: %int_64.fab: Core.IntLiteral = int_value 64 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete]
|
||||
|
||||
@@ -291,7 +291,7 @@ fn H() {
|
||||
// CHECK:STDOUT: %Main.import_ref.8e0 = import_ref Main//extend_generic_base, inst26 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.7f7: @Base.%Base.elem (%Base.elem.9af) = import_ref Main//extend_generic_base, loc5_8, loaded [concrete = %.e66]
|
||||
// CHECK:STDOUT: %Main.import_ref.bd0: <witness> = import_ref Main//extend_generic_base, loc14_1, loaded [concrete = constants.%complete_type.b07]
|
||||
// CHECK:STDOUT: %Main.import_ref.f6c = import_ref Main//extend_generic_base, inst77 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.f6c = import_ref Main//extend_generic_base, inst76 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.d24 = import_ref Main//extend_generic_base, loc13_27, unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.77a301.2: type = import_ref Main//extend_generic_base, loc13_26, loaded [concrete = constants.%Base.7a8]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
|
||||
+1
-1
@@ -310,7 +310,7 @@ class Class(U:! type) {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Main.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Main//foo, inst143 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %Main.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Main//foo, inst140 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Main.import_ref.773), @impl.a8d [concrete]
|
||||
// CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//foo, loc4_13, loaded [symbolic = @Class.%T.1 (constants.%T)]
|
||||
// CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)]
|
||||
|
||||
+2
-2
@@ -234,11 +234,11 @@ fn Run() {
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @impl.c81 [concrete]
|
||||
// CHECK:STDOUT: %.d33: %Field.elem = field_decl x, element0 [concrete]
|
||||
// CHECK:STDOUT: %Main.import_ref.8f24d3.2: <witness> = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst60 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst59 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.760: %F.type = import_ref Main//a, loc14_21, loaded [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %Main.import_ref.26e: %G.type = import_ref Main//a, loc15_27, loaded [concrete = constants.%G]
|
||||
// CHECK:STDOUT: %Main.import_ref.8f24d3.3: <witness> = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst60 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst59 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.42a = import_ref Main//a, loc14_21, unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.67a = import_ref Main//a, loc15_27, unloaded
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ fn Run() {
|
||||
// CHECK:STDOUT: %Main.import_ref.e67: %Base.elem = import_ref Main//a, loc8_8, loaded [concrete = %.720]
|
||||
// CHECK:STDOUT: %Main.import_ref.2e4 = import_ref Main//a, loc9_13, unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.c5f: <witness> = import_ref Main//a, loc14_1, loaded [concrete = constants.%complete_type.15c]
|
||||
// CHECK:STDOUT: %Main.import_ref.9a9 = import_ref Main//a, inst74 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.9a9 = import_ref Main//a, inst73 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.7e5 = import_ref Main//a, loc13_20, unloaded
|
||||
// CHECK:STDOUT: %Main.import_ref.a21640.2: type = import_ref Main//a, loc13_16, loaded [concrete = constants.%Base]
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
|
||||
+1
-1
@@ -596,9 +596,9 @@ var arr: array(i32, (1 as i32) + (2 as i32)) = (3, 4, (3 as i32) + (4 as i32));
|
||||
// CHECK:STDOUT: %Self.65a: %As.type.eed = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.843: type = fn_type @Convert.1, @As(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.95f: %Convert.type.843 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type.04d: type = facet_access_type %Self.65a [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.ca4: type = pattern_type %Self.as_type.04d [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %As.assoc_type.760: type = assoc_entity_type @As, @As(%T) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.076: %As.assoc_type.760 = assoc_entity element0, imports.%Core.import_ref.708 [symbolic]
|
||||
// CHECK:STDOUT: %As.type.a6d: type = facet_type <@As, @As(%i32.builtin)> [concrete]
|
||||
|
||||
@@ -865,9 +865,9 @@ import library "extern_api";
|
||||
// CHECK:STDOUT: %pattern_type.501: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
|
||||
// CHECK:STDOUT: %C: %C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.dd4: type = tuple_type (%i32) [concrete]
|
||||
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.f5f: type = pattern_type %struct_type.c [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.dd4: type = tuple_type (%i32) [concrete]
|
||||
// CHECK:STDOUT: %D.type: type = fn_type @D [concrete]
|
||||
// CHECK:STDOUT: %D: %D.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %E.type: type = fn_type @E [concrete]
|
||||
|
||||
@@ -318,9 +318,9 @@ fn InstanceCallFail() {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.c38: type = facet_type <@ImplicitAs, @ImplicitAs(%NonInstance2.type)> [concrete]
|
||||
@@ -500,9 +500,9 @@ fn InstanceCallFail() {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.c69: type = facet_type <@ImplicitAs, @ImplicitAs(%NonInstance3.type)> [concrete]
|
||||
|
||||
@@ -466,9 +466,9 @@ fn InstanceCallImportFail() {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.a4a: type = facet_type <@ImplicitAs, @ImplicitAs(%NonInstance.type)> [concrete]
|
||||
@@ -652,9 +652,9 @@ fn InstanceCallImportFail() {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.a4a: type = facet_type <@ImplicitAs, @ImplicitAs(%NonInstance.type)> [concrete]
|
||||
|
||||
@@ -166,9 +166,9 @@ fn G(U:! Different) -> U.(Interface.T);
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %Dest [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.dc8: type = facet_type <@ImplicitAs, @ImplicitAs(type)> [concrete]
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ fn F() {
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .n = <unexpected>.inst45.loc15_5
|
||||
// CHECK:STDOUT: .n = <unexpected>.inst44.loc15_5
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
|
||||
@@ -267,10 +267,10 @@ fn F() { ()[()]; }
|
||||
// CHECK:STDOUT: %Self.30a: %IndexWith.type.bd2 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %At.type.cf4: type = fn_type @At.1, @IndexWith(%SubscriptType) [symbolic]
|
||||
// CHECK:STDOUT: %At.281: %At.type.cf4 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %SubscriptType [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.30a [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.e1a: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %SubscriptType [symbolic]
|
||||
// CHECK:STDOUT: %IndexWith.assoc_type.290: type = assoc_entity_type @IndexWith, @IndexWith(%SubscriptType) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.af8: %IndexWith.assoc_type.290 = assoc_entity element0, imports.%Core.import_ref.e99 [symbolic]
|
||||
// CHECK:STDOUT: %IndexWith.type.a51: type = facet_type <@IndexWith, @IndexWith(%empty_tuple.type)> [concrete]
|
||||
|
||||
@@ -296,9 +296,9 @@ fn F0(n: i32) -> P.D {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%T) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.61e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [concrete]
|
||||
@@ -1101,9 +1101,9 @@ fn F0(n: i32) -> P.D {
|
||||
// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert.1, @ImplicitAs(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.f3e: type = pattern_type %Self.as_type [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%T) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.9f5: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.61e: type = facet_type <@ImplicitAs, @ImplicitAs(%i32.builtin)> [concrete]
|
||||
|
||||
+5
-5
@@ -347,12 +347,12 @@ var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst119 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst116 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @impl.a8d [concrete]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1423 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1418 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -526,7 +526,7 @@ var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1423 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1418 [no loc], unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -643,11 +643,11 @@ var c_bad: C({.a = 3, .b = 4}) = F();
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst119 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst116 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @impl.a8d [concrete]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1423 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst1418 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+5
-5
@@ -377,12 +377,12 @@ var c_bad: C((3, 4)) = F();
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst121 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst118 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @impl.a8d [concrete]
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1460 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1455 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -572,7 +572,7 @@ var c_bad: C((3, 4)) = F();
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1460 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1455 [no loc], unloaded
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -690,11 +690,11 @@ var c_bad: C((3, 4)) = F();
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst121 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.773: @impl.a8d.%Convert.type (%Convert.type.9a6) = import_ref Implicit//default, inst118 [indirect], loaded [symbolic = @impl.a8d.%Convert (constants.%Convert.458)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @impl.a8d [concrete]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.48d: %tuple.type.c2c = import_ref Implicit//default, loc7_9, loaded [symbolic = @C.%X (constants.%X)]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.8f2: <witness> = import_ref Implicit//default, loc7_26, loaded [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1460 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Implicit.import_ref.964 = import_ref Implicit//default, inst1455 [no loc], unloaded
|
||||
// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -37,6 +37,28 @@ fn G() {
|
||||
F(v, ());
|
||||
}
|
||||
|
||||
// --- public_function.carbon
|
||||
|
||||
package P;
|
||||
|
||||
fn F(x: (), var y: ());
|
||||
|
||||
// --- public_function.impl.carbon
|
||||
|
||||
impl package P;
|
||||
|
||||
fn F(x: (), var y: ()) {}
|
||||
|
||||
// --- use_public_function.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import P;
|
||||
|
||||
fn G() {
|
||||
P.F((), ());
|
||||
}
|
||||
|
||||
// --- fail_nested.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
@@ -94,6 +116,17 @@ class C {
|
||||
fn F[var self: Self]();
|
||||
}
|
||||
|
||||
// --- nested_match.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F() -> ();
|
||||
|
||||
fn G() {
|
||||
// The SemIR should contain only two temporary_storage insts, not three.
|
||||
let (x: (), var y: (), z: ()) = (F(), F(), F());
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- basic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -274,6 +307,152 @@ class C {
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- public_function.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: }
|
||||
// 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: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type = value_param_pattern %x.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type = binding_pattern y [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt: %pattern_type = ref_param_pattern %y.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: %.loc4_13: %pattern_type = var_pattern %y.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %empty_tuple.type = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc4_10.1: type = splice_block %.loc4_10.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc4_10.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc4_10.3: type = converted %.loc4_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %y.param: ref %empty_tuple.type = ref_param call_param1
|
||||
// CHECK:STDOUT: %.loc4_21.1: type = splice_block %.loc4_21.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc4_21.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc4_21.3: type = converted %.loc4_21.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y: ref %empty_tuple.type = bind_name y, %y.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%x.param: %empty_tuple.type, %y.param: %empty_tuple.type);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- public_function.impl.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %P.import = import P
|
||||
// CHECK:STDOUT: %default.import = import <none>
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type = value_param_pattern %x.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type = binding_pattern y [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt: %pattern_type = ref_param_pattern %y.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: %.loc4_13: %pattern_type = var_pattern %y.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %empty_tuple.type = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc4_10.1: type = splice_block %.loc4_10.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc4_10.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc4_10.3: type = converted %.loc4_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %x.param
|
||||
// CHECK:STDOUT: %y.param: ref %empty_tuple.type = ref_param call_param1
|
||||
// CHECK:STDOUT: %.loc4_21.1: type = splice_block %.loc4_21.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc4_21.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc4_21.3: type = converted %.loc4_21.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y: ref %empty_tuple.type = bind_name y, %y.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%x.param: %empty_tuple.type, %y.param: %empty_tuple.type) [from "public_function.carbon"] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_public_function.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %P: <namespace> = namespace file.%P.import, [concrete] {
|
||||
// CHECK:STDOUT: .F = %P.F
|
||||
// CHECK:STDOUT: import P//default
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %P.F: %F.type = import_ref P//default, F, loaded [concrete = constants.%F]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .P = imports.%P
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %P.import = import P
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %P.ref: <namespace> = name_ref P, imports.%P [concrete = imports.%P]
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, imports.%P.F [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %.loc7_8.1: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc7_12.1: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc7_8.2: %empty_tuple.type = converted %.loc7_8.1, %empty_tuple [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.1: ref %empty_tuple.type = temporary_storage
|
||||
// CHECK:STDOUT: %.loc7_12.2: init %empty_tuple.type = tuple_init () to %.1 [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.2: init %empty_tuple.type = converted %.loc7_12.1, %.loc7_12.2 [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: assign %.1, %.2
|
||||
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%.loc7_8.2, %.1)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F [from "public_function.carbon"];
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_nested.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -417,3 +596,83 @@ class C {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%self.param: %C);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- nested_match.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.8c1: type = pattern_type %tuple.type [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: }
|
||||
// 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: %return.patt: %pattern_type.cb1 = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern %return.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc4_12.1: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc4_12.2: type = converted %.loc4_12.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() -> %empty_tuple.type;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.cb1 = binding_pattern y [concrete]
|
||||
// CHECK:STDOUT: %.loc8_15: %pattern_type.cb1 = var_pattern %y.patt [concrete]
|
||||
// CHECK:STDOUT: %z.patt: %pattern_type.cb1 = binding_pattern z [concrete]
|
||||
// CHECK:STDOUT: %.loc8_31: %pattern_type.8c1 = tuple_pattern (%x.patt, %.loc8_15, %z.patt) [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y.var: ref %empty_tuple.type = var y
|
||||
// CHECK:STDOUT: %F.ref.loc8_36: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %F.call.loc8_38: init %empty_tuple.type = call %F.ref.loc8_36()
|
||||
// CHECK:STDOUT: %F.ref.loc8_41: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %F.call.loc8_43: init %empty_tuple.type = call %F.ref.loc8_41()
|
||||
// CHECK:STDOUT: %F.ref.loc8_46: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %F.call.loc8_48: init %empty_tuple.type = call %F.ref.loc8_46()
|
||||
// CHECK:STDOUT: %.loc8_49: %tuple.type = tuple_literal (%F.call.loc8_38, %F.call.loc8_43, %F.call.loc8_48)
|
||||
// CHECK:STDOUT: %.loc8_12.1: type = splice_block %.loc8_12.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc8_12.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.3: type = converted %.loc8_12.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8_38.1: ref %empty_tuple.type = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_38.2: ref %empty_tuple.type = temporary %.loc8_38.1, %F.call.loc8_38
|
||||
// CHECK:STDOUT: %x: ref %empty_tuple.type = bind_name x, %.loc8_38.2
|
||||
// CHECK:STDOUT: assign %y.var, %F.call.loc8_43
|
||||
// CHECK:STDOUT: %.loc8_23.1: type = splice_block %.loc8_23.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc8_23.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc8_23.3: type = converted %.loc8_23.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y: ref %empty_tuple.type = bind_name y, %y.var
|
||||
// CHECK:STDOUT: %.loc8_30.1: type = splice_block %.loc8_30.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc8_30.2: %empty_tuple.type = tuple_literal ()
|
||||
// CHECK:STDOUT: %.loc8_30.3: type = converted %.loc8_30.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8_48.1: ref %empty_tuple.type = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_48.2: ref %empty_tuple.type = temporary %.loc8_48.1, %F.call.loc8_48
|
||||
// CHECK:STDOUT: %z: ref %empty_tuple.type = bind_name z, %.loc8_48.2
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -56,8 +56,8 @@ struct FunctionFields {
|
||||
// is not virtual (ie: (virtual_modifier == None) == (virtual_index == -1)).
|
||||
int32_t virtual_index = -1;
|
||||
|
||||
// The implicit self parameter, if any, in implicit_param_patterns_id from
|
||||
// EntityWithParamsBase.
|
||||
// The implicit self parameter pattern, if any, in
|
||||
// implicit_param_patterns_id from EntityWithParamsBase.
|
||||
InstId self_param_id = InstId::None;
|
||||
|
||||
// The following member is set on the first call to the function, or at the
|
||||
|
||||
@@ -79,7 +79,7 @@ struct InstLikeTypeInfo<InstCat> : InstLikeTypeInfoBase<InstCat> {
|
||||
static_assert(HasKindMemberAsField<InstCat>,
|
||||
"Instruction category should have a kind field");
|
||||
static auto GetKind(InstCat cat) -> InstKind { return cat.kind; }
|
||||
static auto IsKind(InstKind kind) -> bool {
|
||||
static constexpr auto IsKind(InstKind kind) -> bool {
|
||||
for (InstKind k : InstCat::Kinds) {
|
||||
if (k == kind) {
|
||||
return true;
|
||||
@@ -100,6 +100,10 @@ struct InstLikeTypeInfo<InstCat> : InstLikeTypeInfoBase<InstCat> {
|
||||
}
|
||||
};
|
||||
|
||||
// HasInstCategory is true if T::Kind is an element of InstCat::Kinds.
|
||||
template <typename InstCat, typename T>
|
||||
concept HasInstCategory = InstLikeTypeInfo<InstCat>::IsKind(T::Kind);
|
||||
|
||||
// A type is InstLike if InstLikeTypeInfo is defined for it.
|
||||
template <typename T>
|
||||
concept InstLikeType = requires { sizeof(InstLikeTypeInfo<T>); };
|
||||
|
||||
Reference in New Issue
Block a user