-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Support for lowering references to imported var
s.
#5513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
e390072
80433b7
d3fe9c9
bde4646
0a83d81
9ccb0ce
8ba6e57
a4e3979
7ba6227
1e47473
fcf6b98
26c7bd9
ddbc443
93dfb0a
78070a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
#include "toolchain/check/inst.h" | ||
#include "toolchain/check/name_lookup.h" | ||
#include "toolchain/check/type.h" | ||
#include "toolchain/check/type_completion.h" | ||
#include "toolchain/parse/node_ids.h" | ||
#include "toolchain/sem_ir/constant.h" | ||
#include "toolchain/sem_ir/file.h" | ||
|
@@ -1238,8 +1239,11 @@ template <typename InstT> | |
static auto ResolveAsUnique(ImportRefResolver& resolver, | ||
SemIR::InstId import_inst_id, InstT inst) | ||
-> ResolveResult { | ||
static_assert(InstT::Kind.constant_kind() == SemIR::InstConstantKind::Unique, | ||
"Use ResolveAsDeduplicated"); | ||
static_assert( | ||
InstT::Kind.constant_kind() == SemIR::InstConstantKind::Unique || | ||
InstT::Kind.constant_kind() == | ||
SemIR::InstConstantKind::ConditionalUnique, | ||
"Use ResolveAsDeduplicated"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it could be, but we can't provide a custom error message so easily that way. Are you thinking that we give the two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm just ambivalent about the
I mainly noted it, though, since I've recently bumped into issues with static_assert and having to migrate things to requires. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But note, I also am hesitant to just churn code when I don't see a benefit. It's not like I think overloading would really fix an issue. I just am losing my love for static_assert when requires would suffice. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switched to a concept. |
||
CARBON_CHECK(!resolver.HasNewWork()); | ||
auto inst_id = AddPlaceholderImportedInst(resolver, import_inst_id, inst); | ||
auto const_id = SetConstantValue(resolver.local_context(), inst_id, inst); | ||
|
@@ -1455,24 +1459,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, | |
.index = inst.index}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Vtable inst) | ||
-> ResolveResult { | ||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto virtual_functions = | ||
GetLocalInstBlockContents(resolver, inst.virtual_functions_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
auto virtual_functions_id = GetLocalCanonicalInstBlockId( | ||
resolver, inst.virtual_functions_id, virtual_functions); | ||
return ResolveAsDeduplicated<SemIR::Vtable>( | ||
resolver, | ||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( | ||
type_const_id), | ||
.virtual_functions_id = virtual_functions_id}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::BindAlias inst) -> ResolveResult { | ||
auto value_id = GetLocalConstantId(resolver, inst.value_id); | ||
|
@@ -1507,16 +1493,18 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, | |
BindingPatternT inst, | ||
SemIR::InstId import_inst_id) -> ResolveResult { | ||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id); | ||
const auto& import_entity_name = | ||
resolver.import_entity_names().Get(inst.entity_name_id); | ||
auto parent_scope_id = | ||
GetLocalNameScopeId(resolver, import_entity_name.parent_scope_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
const auto& import_entity_name = | ||
resolver.import_entity_names().Get(inst.entity_name_id); | ||
auto name_id = GetLocalNameId(resolver, import_entity_name.name_id); | ||
auto entity_name_id = resolver.local_entity_names().Add( | ||
{.name_id = name_id, | ||
.parent_scope_id = SemIR::NameScopeId::None, | ||
.parent_scope_id = parent_scope_id, | ||
.bind_index_value = import_entity_name.bind_index().index, | ||
.is_template = import_entity_name.is_template}); | ||
return ResolveAsUnique<BindingPatternT>( | ||
|
@@ -2622,6 +2610,27 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, | |
{.type_id = type_id, .callee_id = callee_id, .specific_id = specific_id}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::StructAccess inst) -> ResolveResult { | ||
auto type_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto struct_id = GetLocalConstantInstId(resolver, inst.struct_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
// A `struct_access` constant requires its struct operand to have a complete | ||
// type. | ||
CompleteTypeOrCheckFail(resolver.local_context(), | ||
resolver.local_insts().Get(struct_id).type_id()); | ||
|
||
return ResolveAsDeduplicated<SemIR::StructAccess>( | ||
resolver, | ||
{.type_id = | ||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), | ||
.struct_id = struct_id, | ||
.index = inst.index}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::StructType inst) -> ResolveResult { | ||
CARBON_CHECK(inst.type_id == SemIR::TypeType::TypeId); | ||
|
@@ -2668,6 +2677,44 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, | |
GetLocalCanonicalInstBlockId(resolver, inst.elements_id, elems)}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::TupleAccess inst) -> ResolveResult { | ||
auto type_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto tuple_id = GetLocalConstantInstId(resolver, inst.tuple_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
// A `tuple_access` constant requires its struct operand to have a complete | ||
// type. | ||
CompleteTypeOrCheckFail(resolver.local_context(), | ||
resolver.local_insts().Get(tuple_id).type_id()); | ||
|
||
return ResolveAsDeduplicated<SemIR::TupleAccess>( | ||
resolver, | ||
{.type_id = | ||
resolver.local_context().types().GetTypeIdForTypeConstantId(type_id), | ||
.tuple_id = tuple_id, | ||
.index = inst.index}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::TuplePattern inst, | ||
SemIR::InstId import_inst_id) -> ResolveResult { | ||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto elements = GetLocalInstBlockContents(resolver, inst.elements_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
return ResolveAsUnique<SemIR::TuplePattern>( | ||
resolver, import_inst_id, | ||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( | ||
type_const_id), | ||
.elements_id = | ||
GetLocalCanonicalInstBlockId(resolver, inst.elements_id, elements)}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::TupleType inst) -> ResolveResult { | ||
CARBON_CHECK(inst.type_id == SemIR::TypeType::TypeId); | ||
|
@@ -2742,6 +2789,40 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, | |
.subpattern_id = subpattern_id}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, | ||
SemIR::VarStorage inst, | ||
SemIR::InstId import_inst_id) -> ResolveResult { | ||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto pattern_id = GetLocalConstantInstId(resolver, inst.pattern_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
return ResolveAsUnique<SemIR::VarStorage>( | ||
resolver, import_inst_id, | ||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( | ||
type_const_id), | ||
.pattern_id = pattern_id}); | ||
} | ||
|
||
static auto TryResolveTypedInst(ImportRefResolver& resolver, SemIR::Vtable inst) | ||
-> ResolveResult { | ||
auto type_const_id = GetLocalConstantId(resolver, inst.type_id); | ||
auto virtual_functions = | ||
GetLocalInstBlockContents(resolver, inst.virtual_functions_id); | ||
if (resolver.HasNewWork()) { | ||
return ResolveResult::Retry(); | ||
} | ||
|
||
auto virtual_functions_id = GetLocalCanonicalInstBlockId( | ||
resolver, inst.virtual_functions_id, virtual_functions); | ||
return ResolveAsDeduplicated<SemIR::Vtable>( | ||
resolver, | ||
{.type_id = resolver.local_context().types().GetTypeIdForTypeConstantId( | ||
type_const_id), | ||
.virtual_functions_id = virtual_functions_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 | ||
|
@@ -2789,10 +2870,6 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, | |
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); | ||
} | ||
case CARBON_KIND(SemIR::BindSymbolicName inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
|
@@ -2898,6 +2975,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, | |
case CARBON_KIND(SemIR::SpecificImplFunction inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
case CARBON_KIND(SemIR::StructAccess inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
case CARBON_KIND(SemIR::StructType inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
|
@@ -2907,6 +2987,12 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, | |
case CARBON_KIND(SemIR::SymbolicBindingPattern inst): { | ||
return TryResolveTypedInst(resolver, inst, inst_id); | ||
} | ||
case CARBON_KIND(SemIR::TupleAccess inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
case CARBON_KIND(SemIR::TuplePattern inst): { | ||
return TryResolveTypedInst(resolver, inst, inst_id); | ||
} | ||
case CARBON_KIND(SemIR::TupleType inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
|
@@ -2922,13 +3008,26 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver, | |
case CARBON_KIND(SemIR::VarPattern inst): { | ||
return TryResolveTypedInst(resolver, inst, inst_id); | ||
} | ||
case CARBON_KIND(SemIR::VarStorage inst): { | ||
return TryResolveTypedInst(resolver, inst, inst_id); | ||
} | ||
case CARBON_KIND(SemIR::Vtable inst): { | ||
return TryResolveTypedInst(resolver, inst); | ||
} | ||
default: { | ||
auto inst_constant_id = resolver.import_constant_values().Get(inst_id); | ||
if (!inst_constant_id.is_constant()) { | ||
// TODO: Import of non-constant BindNames happens when importing `let` | ||
// declarations. | ||
CARBON_CHECK(untyped_inst.Is<SemIR::BindName>(), | ||
"TryResolveInst on non-constant instruction {0}", | ||
untyped_inst); | ||
return ResolveResult::Done(SemIR::ConstantId::NotConstant); | ||
} | ||
|
||
// This instruction might have a constant value of a different kind. | ||
auto constant_inst_id = | ||
resolver.import_constant_values().GetConstantInstId(inst_id); | ||
resolver.import_constant_values().GetInstId(inst_constant_id); | ||
if (constant_inst_id == inst_id) { | ||
// Produce a diagnostic to provide a source location with the CHECK | ||
// failure. | ||
|
Uh oh!
There was an error while loading. Please reload this page.