mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 08:11:04 +01:00
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:
+20
-10
@@ -96,26 +96,36 @@ class EvalContext {
|
||||
|
||||
// While resolving a specific, map from previous instructions in the eval
|
||||
// block into their evaluated values. These values won't be present on the
|
||||
// specific itself yet, so `GetConstantInSpecific` won't be able to find
|
||||
// them.
|
||||
if (specific_eval_info_) {
|
||||
const auto& symbolic_info =
|
||||
constant_values().GetSymbolicConstant(const_id);
|
||||
if (symbolic_info.index.has_value() &&
|
||||
symbolic_info.generic_id ==
|
||||
specifics().Get(specific_id_).generic_id &&
|
||||
symbolic_info.index.region() == specific_eval_info_->region) {
|
||||
// specific itself yet, so `GetConstantValueInSpecific` won't be able to
|
||||
// find them.
|
||||
const auto& symbolic_info = constant_values().GetSymbolicConstant(const_id);
|
||||
if (specific_eval_info_ && symbolic_info.index.has_value()) {
|
||||
CARBON_CHECK(
|
||||
symbolic_info.generic_id == specifics().Get(specific_id_).generic_id,
|
||||
"Instruction has constant operand in wrong generic");
|
||||
if (symbolic_info.index.region() == specific_eval_info_->region) {
|
||||
auto inst_id = specific_eval_info_->values[symbolic_info.index.index()];
|
||||
CARBON_CHECK(inst_id.has_value(),
|
||||
"Forward reference in eval block: index {0} referenced "
|
||||
"before evaluation",
|
||||
symbolic_info.index.index());
|
||||
return constant_values().Get(inst_id);
|
||||
} else {
|
||||
// TODO: Eliminate this call. This is the only place where we get a
|
||||
// value from a specific without using an InstId. There are three ways
|
||||
// we can get here:
|
||||
// 1) From GetConstantValue(InstId): these can use
|
||||
// GetConstantValueInSpecific.
|
||||
// 2) From GetConstantValue(TypeId): for these, we could change
|
||||
// instructions so they store InstIds instead of TypeIds.
|
||||
// 3) From GetConstantFacetTypeInfo: for these, we could store an
|
||||
// InstId instead of a ConstantId in rewrite_constraints.
|
||||
return GetConstantInSpecific(sem_ir(), specific_id_, const_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Map from a specific constant value to the canonical value.
|
||||
return GetConstantInSpecific(sem_ir(), specific_id_, const_id);
|
||||
return constant_values().Get(symbolic_info.inst_id);
|
||||
}
|
||||
|
||||
// Gets the constant value of the specified instruction in this context.
|
||||
|
||||
@@ -243,7 +243,7 @@ auto EvalConstantInst(Context& context, SemIRLoc loc,
|
||||
|
||||
auto EvalConstantInst(Context& context, SemIRLoc loc,
|
||||
SemIR::ImplWitnessAccess inst) -> ConstantEvalResult {
|
||||
// This is PerformAggregateAccess followed by GetConstantInSpecific.
|
||||
// This is PerformAggregateAccess followed by GetConstantValueInSpecific.
|
||||
if (auto witness =
|
||||
context.insts().TryGetAs<SemIR::ImplWitness>(inst.witness_id)) {
|
||||
auto elements = context.inst_blocks().Get(witness->elements_id);
|
||||
|
||||
@@ -109,10 +109,10 @@ static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id,
|
||||
SemIR::NameId name_id) -> SemIR::InstId {
|
||||
auto result = LookupUnqualifiedName(context, node_id, name_id);
|
||||
SemIR::InstId inst_id = result.scope_result.target_inst_id();
|
||||
auto value = context.insts().Get(inst_id);
|
||||
auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id,
|
||||
value.type_id());
|
||||
CARBON_CHECK(type_id.has_value(), "Missing type for {0}", value);
|
||||
auto type_id = SemIR::GetTypeOfInstInSpecific(context.sem_ir(),
|
||||
result.specific_id, inst_id);
|
||||
CARBON_CHECK(type_id.has_value(), "Missing type for {0}",
|
||||
context.insts().Get(inst_id));
|
||||
|
||||
// If the named entity has a constant value that depends on its specific,
|
||||
// store the specific too.
|
||||
|
||||
@@ -81,9 +81,8 @@ static auto GetSelfFacet(Context& context,
|
||||
SemIR::InstId self_witness_id) -> SemIR::InstId {
|
||||
auto self_binding_id =
|
||||
GetSelfBinding(context, interface_specific_id, generic_id);
|
||||
auto self_binding = context.insts().Get(self_binding_id);
|
||||
auto self_facet_type_id = SemIR::GetTypeInSpecific(
|
||||
context.sem_ir(), interface_specific_id, self_binding.type_id());
|
||||
auto self_facet_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
context.sem_ir(), interface_specific_id, self_binding_id);
|
||||
// Create a facet value to be the value of `Self` in the interface.
|
||||
// TODO: Pass this in instead of creating it here. The caller sometimes
|
||||
// already has a facet value.
|
||||
@@ -190,15 +189,14 @@ auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
|
||||
GetGenericArgsWithSelfType(context, interface_specific_id, generic_id,
|
||||
self_type_id, self_witness_id);
|
||||
auto const_specific_id = MakeSpecific(context, loc, generic_id, arg_ids);
|
||||
return SemIR::GetTypeInSpecific(context.sem_ir(), const_specific_id,
|
||||
context.insts().Get(decl_id).type_id());
|
||||
return SemIR::GetTypeOfInstInSpecific(context.sem_ir(), const_specific_id,
|
||||
decl_id);
|
||||
} else if (auto fn = context.types().TryGetAs<SemIR::FunctionType>(
|
||||
decl.type_id())) {
|
||||
// Form the type of the function within the interface, and attach the `Self`
|
||||
// type.
|
||||
auto interface_fn_type_id =
|
||||
SemIR::GetTypeInSpecific(context.sem_ir(), interface_specific_id,
|
||||
context.insts().Get(decl_id).type_id());
|
||||
auto interface_fn_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
context.sem_ir(), interface_specific_id, decl_id);
|
||||
auto self_facet_id =
|
||||
GetSelfFacet(context, interface_specific_id,
|
||||
context.functions().Get(fn->function_id).generic_id,
|
||||
|
||||
@@ -261,10 +261,11 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
|
||||
// TODO: This duplicates the work that HandleNameAsExpr does. Factor this out.
|
||||
auto inst = context.insts().Get(result.scope_result.target_inst_id());
|
||||
auto type_id = SemIR::GetTypeInSpecific(context.sem_ir(), result.specific_id,
|
||||
inst.type_id());
|
||||
CARBON_CHECK(type_id.has_value(), "Missing type for member {0}", inst);
|
||||
auto type_id =
|
||||
SemIR::GetTypeOfInstInSpecific(context.sem_ir(), result.specific_id,
|
||||
result.scope_result.target_inst_id());
|
||||
CARBON_CHECK(type_id.has_value(), "Missing type for member {0}",
|
||||
context.insts().Get(result.scope_result.target_inst_id()));
|
||||
|
||||
// If the named entity has a constant value that depends on its specific,
|
||||
// store the specific too.
|
||||
|
||||
+24
-15
@@ -203,6 +203,9 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
SemIR::InstId prev_param_pattern_id,
|
||||
SemIR::SpecificId prev_specific_id, bool diagnose,
|
||||
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.
|
||||
@@ -218,9 +221,10 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
"redeclaration differs at {0:implicit |}parameter {1}",
|
||||
Diagnostics::BoolAsSelect, int32_t);
|
||||
context.emitter()
|
||||
.Build(new_param_pattern_id, RedeclParamDiffers, is_implicit_param,
|
||||
.Build(orig_new_param_pattern_id, RedeclParamDiffers, is_implicit_param,
|
||||
param_index + 1)
|
||||
.Note(prev_param_pattern_id, RedeclParamPrevious, is_implicit_param)
|
||||
.Note(orig_prev_param_pattern_id, RedeclParamPrevious,
|
||||
is_implicit_param)
|
||||
.Emit();
|
||||
};
|
||||
|
||||
@@ -232,10 +236,11 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
}
|
||||
|
||||
if (new_param_pattern.Is<SemIR::AddrPattern>()) {
|
||||
new_param_pattern = context.insts().Get(
|
||||
new_param_pattern.As<SemIR::AddrPattern>().inner_id);
|
||||
prev_param_pattern = context.insts().Get(
|
||||
prev_param_pattern.As<SemIR::AddrPattern>().inner_id);
|
||||
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);
|
||||
if (new_param_pattern.kind() != prev_param_pattern.kind()) {
|
||||
emit_diagnostic();
|
||||
return false;
|
||||
@@ -243,10 +248,12 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
}
|
||||
|
||||
if (new_param_pattern.Is<SemIR::AnyParamPattern>()) {
|
||||
new_param_pattern = context.insts().Get(
|
||||
new_param_pattern.As<SemIR::ValueParamPattern>().subpattern_id);
|
||||
prev_param_pattern = context.insts().Get(
|
||||
prev_param_pattern.As<SemIR::ValueParamPattern>().subpattern_id);
|
||||
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;
|
||||
@@ -267,8 +274,8 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
return true;
|
||||
}
|
||||
|
||||
auto prev_param_type_id = SemIR::GetTypeInSpecific(
|
||||
context.sem_ir(), prev_specific_id, prev_param_pattern.type_id());
|
||||
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) {
|
||||
@@ -280,9 +287,11 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
Diagnostics::BoolAsSelect, int32_t, SemIR::TypeId,
|
||||
SemIR::TypeId);
|
||||
context.emitter()
|
||||
.Build(new_param_pattern_id, RedeclParamDiffersType, is_implicit_param,
|
||||
param_index + 1, prev_param_type_id, new_param_pattern.type_id())
|
||||
.Note(prev_param_pattern_id, RedeclParamPrevious, is_implicit_param)
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,13 +215,11 @@ auto FileContext::BuildFunctionTypeInfo(const SemIR::Function& function,
|
||||
/*isVarArg=*/false)};
|
||||
}
|
||||
|
||||
// TODO nit: add is_symbolic() to type_id to forward to
|
||||
// type_id.AsConstantId().is_symbolic(). Update call below too.
|
||||
auto get_llvm_type = [&](SemIR::TypeId type_id) -> llvm::Type* {
|
||||
if (!type_id.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
return GetType(SemIR::GetTypeInSpecific(sem_ir(), specific_id, type_id));
|
||||
return GetType(type_id);
|
||||
};
|
||||
|
||||
// TODO: expose the `Call` parameter patterns in `Function`, and use them here
|
||||
@@ -267,8 +265,8 @@ auto FileContext::BuildFunctionTypeInfo(const SemIR::Function& function,
|
||||
if (!param_pattern_info) {
|
||||
continue;
|
||||
}
|
||||
auto param_type_id = SemIR::GetTypeInSpecific(
|
||||
sem_ir(), specific_id, param_pattern_info->inst.type_id);
|
||||
auto param_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
sem_ir(), specific_id, param_pattern_info->inst_id);
|
||||
CARBON_CHECK(
|
||||
!param_type_id.AsConstantId().is_symbolic(),
|
||||
"Found symbolic type id after resolution when lowering type {0}.",
|
||||
@@ -412,7 +410,7 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
|
||||
++param_index;
|
||||
} else {
|
||||
param_value = llvm::PoisonValue::get(GetType(
|
||||
SemIR::GetTypeInSpecific(sem_ir(), specific_id, param_inst.type_id)));
|
||||
SemIR::GetTypeOfInstInSpecific(sem_ir(), specific_id, param_id)));
|
||||
}
|
||||
// The value of the parameter is the value of the argument.
|
||||
function_lowering.SetLocal(param_id, param_value);
|
||||
|
||||
@@ -442,8 +442,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
|
||||
auto inst_type_id = SemIR::GetTypeInSpecific(
|
||||
context.sem_ir(), context.specific_id(), inst.type_id);
|
||||
auto inst_type_id = SemIR::GetTypeOfInstInSpecific(
|
||||
context.sem_ir(), context.specific_id(), inst_id);
|
||||
|
||||
if (SemIR::ReturnTypeInfo::ForType(context.sem_ir(), inst_type_id)
|
||||
.has_return_slot()) {
|
||||
|
||||
@@ -93,8 +93,7 @@ auto Function::GetDeclaredReturnType(const File& file,
|
||||
if (!return_slot_pattern_id.has_value()) {
|
||||
return TypeId::None;
|
||||
}
|
||||
return GetTypeInSpecific(file, specific_id,
|
||||
file.insts().Get(return_slot_pattern_id).type_id());
|
||||
return GetTypeOfInstInSpecific(file, specific_id, return_slot_pattern_id);
|
||||
}
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
@@ -92,10 +92,12 @@ auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
sem_ir.constant_values().Get(inst_id));
|
||||
}
|
||||
|
||||
auto GetTypeInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
TypeId type_id) -> TypeId {
|
||||
return TypeId::ForTypeConstant(GetConstantInSpecific(
|
||||
sem_ir, specific_id, sem_ir.types().GetConstantId(type_id)));
|
||||
auto GetTypeOfInstInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
InstId inst_id) -> TypeId {
|
||||
auto type_id = sem_ir.insts().Get(inst_id).type_id();
|
||||
auto const_id = sem_ir.types().GetConstantId(type_id);
|
||||
auto specific_const_id = GetConstantInSpecific(sem_ir, specific_id, const_id);
|
||||
return TypeId::ForTypeConstant(specific_const_id);
|
||||
}
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
@@ -157,11 +157,11 @@ auto GetConstantInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
InstId inst_id) -> ConstantId;
|
||||
|
||||
// Gets the substituted value of a potentially generic type within a specific.
|
||||
// Note that this does not perform substitution, and will return `None` if
|
||||
// the substituted type is not yet known.
|
||||
auto GetTypeInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
TypeId type_id) -> TypeId;
|
||||
// Gets the substituted type of an instruction within a specific. Note that this
|
||||
// does not perform substitution, and will return `None` if the substituted type
|
||||
// is not yet known.
|
||||
auto GetTypeOfInstInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||
InstId inst_id) -> TypeId;
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
|
||||
Reference in New Issue
Block a user