From c33adfafd32ed65bc0693bebeb5ae5656624c83c Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 2 Apr 2025 15:52:11 -0700 Subject: [PATCH] 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. --- toolchain/check/eval.cpp | 30 ++++++---- toolchain/check/eval_inst.cpp | 2 +- toolchain/check/handle_name.cpp | 8 +-- toolchain/check/interface.cpp | 14 ++--- toolchain/check/member_access.cpp | 9 +-- toolchain/check/merge.cpp | 39 +++++++----- toolchain/check/pattern_match.cpp | 98 +++++++++++++++++-------------- toolchain/lower/file_context.cpp | 10 ++-- toolchain/lower/handle_call.cpp | 4 +- toolchain/sem_ir/function.cpp | 3 +- toolchain/sem_ir/generic.cpp | 10 ++-- toolchain/sem_ir/generic.h | 10 ++-- 12 files changed, 132 insertions(+), 105 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 84c8435b8ad0..af6c5975afb4 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -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. diff --git a/toolchain/check/eval_inst.cpp b/toolchain/check/eval_inst.cpp index 74d00461e1a8..34bf62a5a779 100644 --- a/toolchain/check/eval_inst.cpp +++ b/toolchain/check/eval_inst.cpp @@ -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(inst.witness_id)) { auto elements = context.inst_blocks().Get(witness->elements_id); diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index 8ff8419321ee..06d1abaa6e74 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -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. diff --git a/toolchain/check/interface.cpp b/toolchain/check/interface.cpp index ac9b4c6fdfce..799d1f7d0138 100644 --- a/toolchain/check/interface.cpp +++ b/toolchain/check/interface.cpp @@ -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( 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, diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 3de69d5c7795..699738b58792 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -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. diff --git a/toolchain/check/merge.cpp b/toolchain/check/merge.cpp index 165a0f4fbd98..11e76bc6e786 100644 --- a/toolchain/check/merge.cpp +++ b/toolchain/check/merge.cpp @@ -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()) { - new_param_pattern = context.insts().Get( - new_param_pattern.As().inner_id); - prev_param_pattern = context.insts().Get( - prev_param_pattern.As().inner_id); + new_param_pattern_id = new_param_pattern.As().inner_id; + new_param_pattern = context.insts().Get(new_param_pattern_id); + prev_param_pattern_id = + prev_param_pattern.As().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()) { - new_param_pattern = context.insts().Get( - new_param_pattern.As().subpattern_id); - prev_param_pattern = context.insts().Get( - prev_param_pattern.As().subpattern_id); + new_param_pattern_id = + new_param_pattern.As().subpattern_id; + new_param_pattern = context.insts().Get(new_param_pattern_id); + prev_param_pattern_id = + prev_param_pattern.As().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; } diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index 73303746c394..591667fe0281 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -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 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( - 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( - 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( - 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( - 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( - 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(context, pattern_loc_id, + AddInst(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(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(), - pattern.loc_id, entry); + DoEmitPatternMatch(context, pattern.As(), + 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()); } } } diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 40689a1e7073..d318a80f669e 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -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); diff --git a/toolchain/lower/handle_call.cpp b/toolchain/lower/handle_call.cpp index 05af264a8730..5c685ea7ebaa 100644 --- a/toolchain/lower/handle_call.cpp +++ b/toolchain/lower/handle_call.cpp @@ -442,8 +442,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, std::vector 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()) { diff --git a/toolchain/sem_ir/function.cpp b/toolchain/sem_ir/function.cpp index 3a68e483680c..10593cad0cdf 100644 --- a/toolchain/sem_ir/function.cpp +++ b/toolchain/sem_ir/function.cpp @@ -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 diff --git a/toolchain/sem_ir/generic.cpp b/toolchain/sem_ir/generic.cpp index 579409d0140c..73aa12a35844 100644 --- a/toolchain/sem_ir/generic.cpp +++ b/toolchain/sem_ir/generic.cpp @@ -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 diff --git a/toolchain/sem_ir/generic.h b/toolchain/sem_ir/generic.h index d527e0ed469a..90c5ab952845 100644 --- a/toolchain/sem_ir/generic.h +++ b/toolchain/sem_ir/generic.h @@ -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