Track the instruction used to name the type and constraint in an impl. (#4368)

This is necessary in order to have access to the specific versions of
their constant values in a generic impl.

Stub out impl deduction.
This commit is contained in:
Richard Smith
2024-10-04 00:06:55 +00:00
committed by GitHub
parent eab5dd6112
commit 568ad197d1
79 changed files with 591 additions and 342 deletions
+48 -21
View File
@@ -56,7 +56,8 @@ auto AddImportIR(Context& context, SemIR::ImportIR import_ir)
}
auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst,
SemIR::EntityNameId entity_name_id) -> SemIR::InstId {
SemIR::EntityNameId entity_name_id =
SemIR::EntityNameId::Invalid) -> SemIR::InstId {
auto import_ir_inst_id = context.import_ir_insts().Add(import_ir_inst);
SemIR::ImportRefUnloaded inst = {.import_ir_inst_id = import_ir_inst_id,
.entity_name_id = entity_name_id};
@@ -70,6 +71,29 @@ auto AddImportRef(Context& context, SemIR::ImportIRInst import_ir_inst,
return import_ref_id;
}
// Adds an import_ref instruction for an instruction that we have already loaded
// from an imported IR, with a known constant value. This is useful when the
// instruction has a symbolic constant value, in order to produce an instruction
// that hold that symbolic constant.
static auto AddLoadedImportRef(Context& context,
SemIR::ImportIRInst import_ir_inst,
SemIR::TypeId type_id,
SemIR::ConstantId const_id) -> SemIR::InstId {
auto import_ir_inst_id = context.import_ir_insts().Add(import_ir_inst);
SemIR::ImportRefLoaded inst = {
.type_id = type_id,
.import_ir_inst_id = import_ir_inst_id,
.entity_name_id = SemIR::EntityNameId::Invalid};
auto inst_id = context.AddPlaceholderInstInNoBlock(
context.MakeImportedLocAndInst(import_ir_inst_id, inst));
context.import_ref_ids().push_back(inst_id);
context.constant_values().Set(inst_id, const_id);
context.import_ir_constant_values()[import_ir_inst.ir_id.index].Set(
import_ir_inst.inst_id, const_id);
return inst_id;
}
auto GetCanonicalImportIRInst(Context& context, const SemIR::File* cursor_ir,
SemIR::InstId cursor_inst_id)
-> SemIR::ImportIRInst {
@@ -115,8 +139,7 @@ auto VerifySameCanonicalImportIRInst(Context& context, SemIR::InstId prev_id,
return;
}
auto conflict_id =
AddImportRef(context, {.ir_id = new_ir_id, .inst_id = new_inst_id},
SemIR::EntityNameId::Invalid);
AddImportRef(context, {.ir_id = new_ir_id, .inst_id = new_inst_id});
context.DiagnoseDuplicateName(conflict_id, prev_id);
}
@@ -902,8 +925,7 @@ class ImportRefResolver {
SemIR::NameScope& new_scope) -> void {
for (auto entry : import_scope.names) {
auto ref_id = AddImportRef(
context_, {.ir_id = import_ir_id_, .inst_id = entry.inst_id},
SemIR::EntityNameId::Invalid);
context_, {.ir_id = import_ir_id_, .inst_id = entry.inst_id});
new_scope.AddRequired({.name_id = GetLocalNameId(entry.name_id),
.inst_id = ref_id,
.access_kind = entry.access_kind});
@@ -923,8 +945,7 @@ class ImportRefResolver {
new_associated_entities.reserve(associated_entities.size());
for (auto inst_id : associated_entities) {
new_associated_entities.push_back(
AddImportRef(context_, {.ir_id = import_ir_id_, .inst_id = inst_id},
SemIR::EntityNameId::Invalid));
AddImportRef(context_, {.ir_id = import_ir_id_, .inst_id = inst_id}));
}
return context_.inst_blocks().Add(new_associated_entities);
}
@@ -1143,8 +1164,7 @@ class ImportRefResolver {
// Add a lazy reference to the target declaration.
auto decl_id = AddImportRef(
context_, {.ir_id = import_ir_id_, .inst_id = inst.decl_id},
SemIR::EntityNameId::Invalid);
context_, {.ir_id = import_ir_id_, .inst_id = inst.decl_id});
return ResolveAs<SemIR::AssociatedEntity>(
{.type_id = context_.GetTypeIdForTypeConstant(type_const_id),
@@ -1589,8 +1609,8 @@ class ImportRefResolver {
AddImportIRInst(import_impl.latest_decl_id()), impl_decl));
impl_decl.impl_id = context_.impls().Add(
{GetIncompleteLocalEntityBase(impl_decl_id, import_impl),
{.self_id = SemIR::TypeId::Invalid,
.constraint_id = SemIR::TypeId::Invalid,
{.self_id = SemIR::InstId::Invalid,
.constraint_id = SemIR::InstId::Invalid,
.witness_id = SemIR::InstId::Invalid}});
// Write the impl ID into the ImplDecl.
@@ -1654,8 +1674,10 @@ class ImportRefResolver {
auto parent_scope_id = GetLocalNameScopeId(import_impl.parent_scope_id);
LoadLocalParamConstantIds(import_impl.implicit_param_refs_id);
auto generic_data = GetLocalGenericData(import_impl.generic_id);
auto self_const_id = GetLocalConstantId(import_impl.self_id);
auto constraint_const_id = GetLocalConstantId(import_impl.constraint_id);
auto self_const_id = GetLocalConstantId(
import_ir_.constant_values().Get(import_impl.self_id));
auto constraint_const_id = GetLocalConstantId(
import_ir_.constant_values().Get(import_impl.constraint_id));
if (HasNewWork()) {
return Retry(impl_const_id);
@@ -1668,14 +1690,21 @@ class ImportRefResolver {
CARBON_CHECK(!import_impl.param_refs_id.is_valid() &&
!new_impl.param_refs_id.is_valid());
SetGenericData(import_impl.generic_id, new_impl.generic_id, generic_data);
new_impl.self_id = context_.GetTypeIdForTypeConstant(self_const_id);
new_impl.constraint_id =
context_.GetTypeIdForTypeConstant(constraint_const_id);
// Create instructions for self and constraint to hold the symbolic constant
// value for a generic impl.
new_impl.self_id = AddLoadedImportRef(
context_, {.ir_id = import_ir_id_, .inst_id = import_impl.self_id},
SemIR::TypeId::TypeType, self_const_id);
new_impl.constraint_id = AddLoadedImportRef(
context_,
{.ir_id = import_ir_id_, .inst_id = import_impl.constraint_id},
SemIR::TypeId::TypeType, constraint_const_id);
if (import_impl.is_defined()) {
auto witness_id = AddImportRef(
context_, {.ir_id = import_ir_id_, .inst_id = import_impl.witness_id},
SemIR::EntityNameId::Invalid);
context_,
{.ir_id = import_ir_id_, .inst_id = import_impl.witness_id});
AddImplDefinition(import_impl, new_impl, witness_id);
}
@@ -1683,9 +1712,7 @@ class ImportRefResolver {
// file, add this to impl lookup so that it can be found by redeclarations
// in the current file.
if (import_ir_id_ == SemIR::ImportIRId::ApiForImpl) {
context_.impls()
.GetOrAddLookupBucket(new_impl.self_id, new_impl.constraint_id)
.push_back(impl_id);
context_.impls().GetOrAddLookupBucket(new_impl).push_back(impl_id);
}
return ResolveAsConstant(impl_const_id);