mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 08:54:47 +01:00
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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user