Replace GetTypeInSpecific with GetTypeOfInstInSpecific. (#5232)

Reduce usage of `GetConstantInSpecific` to a single caller in constant
evaluation, with a TODO to remove that.

This gets us closer to being able to fully perform type-checking against
abstract types instead of types anchored within a particular generic.
This commit is contained in:
Richard Smith
2025-04-02 22:52:11 +00:00
committed by GitHub
parent 077cf56a8a
commit c33adfafd3
12 changed files with 132 additions and 105 deletions
+54 -44
View File
@@ -91,25 +91,33 @@ class MatchContext {
// equal to `context.insts().GetLocId(entry.pattern_id)`.
auto DoEmitPatternMatch(Context& context,
SemIR::AnyBindingPattern binding_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context, SemIR::AddrPattern addr_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context,
SemIR::ValueParamPattern param_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context,
SemIR::RefParamPattern param_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context,
SemIR::OutParamPattern param_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context,
SemIR::ReturnSlotPattern return_slot_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context, SemIR::VarPattern var_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
auto DoEmitPatternMatch(Context& context, SemIR::TuplePattern tuple_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void;
SemIR::InstId pattern_inst_id, WorkItem entry)
-> void;
// The stack of work to be processed.
llvm::SmallVector<WorkItem> stack_;
@@ -192,7 +200,7 @@ static auto InsertHere(Context& context, SemIR::ExprRegionId region_id)
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::AnyBindingPattern binding_pattern,
SemIR::LocId /*pattern_loc_id*/,
SemIR::InstId /*pattern_inst_id*/,
MatchContext::WorkItem entry) -> void {
if (kind_ == MatchKind::Caller) {
CARBON_CHECK(binding_pattern.kind == SemIR::SymbolicBindingPattern::Kind,
@@ -233,7 +241,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::AddrPattern addr_pattern,
SemIR::LocId /*pattern_loc_id*/,
SemIR::InstId /*pattern_inst_id*/,
WorkItem entry) -> void {
CARBON_CHECK(kind_ != MatchKind::Local);
if (kind_ == MatchKind::Callee) {
@@ -272,7 +280,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::ValueParamPattern param_pattern,
SemIR::LocId pattern_loc_id,
SemIR::InstId pattern_inst_id,
WorkItem entry) -> void {
switch (kind_) {
case MatchKind::Caller: {
@@ -287,8 +295,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
results_.push_back(ConvertToValueOfType(
context, context.insts().GetLocId(entry.scrutinee_id),
entry.scrutinee_id,
SemIR::GetTypeInSpecific(context.sem_ir(), callee_specific_id_,
param_pattern.type_id)));
SemIR::GetTypeOfInstInSpecific(
context.sem_ir(), callee_specific_id_, pattern_inst_id)));
}
// Do not traverse farther, because the caller side of the pattern
// ends here.
@@ -299,7 +307,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
param_pattern.index = NextRuntimeIndex();
ReplaceInstBeforeConstantUse(context, entry.pattern_id, param_pattern);
auto param_id = AddInst<SemIR::ValueParam>(
context, pattern_loc_id,
context, context.insts().GetLocId(pattern_inst_id),
{.type_id = param_pattern.type_id,
.index = param_pattern.index,
.pretty_name_id = SemIR::GetPrettyNameFromPatternId(
@@ -317,7 +325,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::RefParamPattern param_pattern,
SemIR::LocId pattern_loc_id,
SemIR::InstId pattern_inst_id,
WorkItem entry) -> void {
switch (kind_) {
case MatchKind::Caller: {
@@ -340,7 +348,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
param_pattern.index = NextRuntimeIndex();
ReplaceInstBeforeConstantUse(context, entry.pattern_id, param_pattern);
auto param_id = AddInst<SemIR::RefParam>(
context, pattern_loc_id,
context, context.insts().GetLocId(pattern_inst_id),
{.type_id = param_pattern.type_id,
.index = param_pattern.index,
.pretty_name_id = SemIR::GetPrettyNameFromPatternId(
@@ -358,7 +366,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::OutParamPattern param_pattern,
SemIR::LocId pattern_loc_id,
SemIR::InstId pattern_inst_id,
WorkItem entry) -> void {
switch (kind_) {
case MatchKind::Caller: {
@@ -368,9 +376,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
param_pattern.index.index);
CARBON_CHECK(entry.scrutinee_id.has_value());
CARBON_CHECK(context.insts().Get(entry.scrutinee_id).type_id() ==
SemIR::GetTypeInSpecific(context.sem_ir(),
callee_specific_id_,
param_pattern.type_id));
SemIR::GetTypeOfInstInSpecific(
context.sem_ir(), callee_specific_id_, pattern_inst_id));
results_.push_back(entry.scrutinee_id);
// Do not traverse farther, because the caller side of the pattern
// ends here.
@@ -383,7 +390,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
param_pattern.index = NextRuntimeIndex();
ReplaceInstBeforeConstantUse(context, entry.pattern_id, param_pattern);
auto param_id = AddInst<SemIR::OutParam>(
context, pattern_loc_id,
context, context.insts().GetLocId(pattern_inst_id),
{.type_id = param_pattern.type_id,
.index = param_pattern.index,
.pretty_name_id = SemIR::GetPrettyNameFromPatternId(
@@ -401,10 +408,10 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(
Context& context, SemIR::ReturnSlotPattern return_slot_pattern,
SemIR::LocId pattern_loc_id, WorkItem entry) -> void {
SemIR::InstId pattern_inst_id, WorkItem entry) -> void {
CARBON_CHECK(kind_ == MatchKind::Callee);
auto return_slot_id = AddInst<SemIR::ReturnSlot>(
context, pattern_loc_id,
context, context.insts().GetLocId(pattern_inst_id),
{.type_id = return_slot_pattern.type_id,
.type_inst_id = return_slot_pattern.type_inst_id,
.storage_id = entry.scrutinee_id});
@@ -417,7 +424,7 @@ auto MatchContext::DoEmitPatternMatch(
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::VarPattern var_pattern,
SemIR::LocId pattern_loc_id,
SemIR::InstId pattern_inst_id,
WorkItem entry) -> void {
auto storage_id = SemIR::InstId::None;
switch (kind_) {
@@ -439,7 +446,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
}
case MatchKind::Caller: {
storage_id = AddInstWithCleanup<SemIR::TemporaryStorage>(
context, pattern_loc_id, {.type_id = var_pattern.type_id});
context, context.insts().GetLocId(pattern_inst_id),
{.type_id = var_pattern.type_id});
CARBON_CHECK(entry.scrutinee_id.has_value());
break;
}
@@ -451,11 +459,11 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
context.global_init().Resume();
}
if (entry.scrutinee_id.has_value()) {
auto init_id =
Initialize(context, pattern_loc_id, storage_id, entry.scrutinee_id);
auto loc_id = context.insts().GetLocId(pattern_inst_id);
auto init_id = Initialize(context, loc_id, storage_id, entry.scrutinee_id);
// TODO: Consider using different instruction kinds for assignment
// versus initialization.
AddInst<SemIR::Assign>(context, pattern_loc_id,
AddInst<SemIR::Assign>(context, loc_id,
{.lhs_id = storage_id, .rhs_id = init_id});
}
AddWork(
@@ -467,7 +475,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
auto MatchContext::DoEmitPatternMatch(Context& context,
SemIR::TuplePattern tuple_pattern,
SemIR::LocId pattern_loc_id,
SemIR::InstId pattern_inst_id,
WorkItem entry) -> void {
if (tuple_pattern.type_id == SemIR::ErrorInst::SingletonTypeId) {
return;
@@ -483,7 +491,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
};
if (!entry.scrutinee_id.has_value()) {
CARBON_CHECK(kind_ == MatchKind::Callee);
context.TODO(pattern_loc_id,
context.TODO(pattern_inst_id,
"Support patterns besides bindings in parameter list");
return;
}
@@ -496,7 +504,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
"tuple pattern expects {0} element{0:s}, but tuple "
"literal has {1}",
Diagnostics::IntAsSelect, Diagnostics::IntAsSelect);
context.emitter().Emit(pattern_loc_id, TuplePatternSizeDoesntMatchLiteral,
context.emitter().Emit(pattern_inst_id,
TuplePatternSizeDoesntMatchLiteral,
subpattern_ids.size(), subscrutinee_ids.size());
return;
}
@@ -505,7 +514,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context,
}
auto converted_scrutinee = ConvertToValueOrRefOfType(
context, pattern_loc_id, entry.scrutinee_id, tuple_pattern.type_id);
context, context.insts().GetLocId(pattern_inst_id), entry.scrutinee_id,
tuple_pattern.type_id);
if (auto scrutinee_value =
context.insts().TryGetAs<SemIR::TupleValue>(converted_scrutinee)) {
add_all_subscrutinees(
@@ -541,44 +551,44 @@ auto MatchContext::EmitPatternMatch(Context& context,
builder.Note(entry.pattern_id, InCallToFunctionParam);
}
});
auto pattern = context.insts().GetWithLocId(entry.pattern_id);
CARBON_KIND_SWITCH(pattern.inst) {
auto pattern = context.insts().Get(entry.pattern_id);
CARBON_KIND_SWITCH(pattern) {
case SemIR::BindingPattern::Kind:
case SemIR::SymbolicBindingPattern::Kind: {
DoEmitPatternMatch(context, pattern.inst.As<SemIR::AnyBindingPattern>(),
pattern.loc_id, entry);
DoEmitPatternMatch(context, pattern.As<SemIR::AnyBindingPattern>(),
entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::AddrPattern addr_pattern): {
DoEmitPatternMatch(context, addr_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, addr_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::ValueParamPattern param_pattern): {
DoEmitPatternMatch(context, param_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, param_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::RefParamPattern param_pattern): {
DoEmitPatternMatch(context, param_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, param_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::OutParamPattern param_pattern): {
DoEmitPatternMatch(context, param_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, param_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::ReturnSlotPattern return_slot_pattern): {
DoEmitPatternMatch(context, return_slot_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, return_slot_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::VarPattern var_pattern): {
DoEmitPatternMatch(context, var_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, var_pattern, entry.pattern_id, entry);
break;
}
case CARBON_KIND(SemIR::TuplePattern tuple_pattern): {
DoEmitPatternMatch(context, tuple_pattern, pattern.loc_id, entry);
DoEmitPatternMatch(context, tuple_pattern, entry.pattern_id, entry);
break;
}
default: {
CARBON_FATAL("Inst kind not handled: {0}", pattern.inst.kind());
CARBON_FATAL("Inst kind not handled: {0}", pattern.kind());
}
}
}