Make template actions refer to values from the specific. (#7663)

When a template action is created, any (non-meta) instruction operand
will refer to instructions in the corresponding generic, or possibly to
a constant. This means that when the action is eventually executed when
forming a specific, it would see the generic value for that operand
rather than the intended specific value.

Fix this by refining `InstId` operands to refer to a corresponding value
in the specific, much like we would when rebuilding a constant in the
eval block.
This commit is contained in:
Richard Smith
2026-08-21 18:34:21 +00:00
committed by GitHub
parent 186a756b72
commit c41033c315
4 changed files with 271 additions and 6 deletions
+18
View File
@@ -214,6 +214,24 @@ static auto RefineTypedOperand(Context& context, SemIR::LocId loc_id,
return inst_id;
}
template <typename DerivedInstIdT>
requires SemIR::Internal::IsIdKindType<DerivedInstIdT> &&
std::derived_from<DerivedInstIdT, SemIR::InstId>
static auto RefineTypedOperand(Context& context, SemIR::LocId /*loc_id*/,
DerivedInstIdT inst_id) -> DerivedInstIdT {
// Refine an instruction that refers to a value within the current generic to
// refer to the corresponding value within the specific. This is analogous to
// the work we do to rebuild generic constants in the eval block, but is done
// as refinement rather than rebuilding since action instructions *only* live
// in the eval block.
auto result = GetOrAddInstWithSpecificConstantValue(context, inst_id);
if constexpr (requires { DerivedInstIdT(result); }) {
return DerivedInstIdT(result);
} else {
return DerivedInstIdT::UnsafeMake(result);
}
}
template <typename BundleT>
static auto RefineTypedOperand(Context& context, SemIR::LocId loc_id,
SemIR::BundleId<BundleT> bundle_id)