mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user