Restructure ArgAndKind as a type-safe generic ID. (#7172)

The key changes here are:
- Relocating and renaming it to align with `IdKind` (and relocating
`ToRaw` and `FromRaw` to follow it).
- Adding a `Dispatch` method that provides a generic overload-based API
for expressing per-ID-kind dispatch, and rewriting existing code to use
it.

Note in particular that using overloads instead of switch cases makes it
possible to generically handle all specializations of a templated ID
type, e.g. `SomeIdType<T>` for all `T`. We have no such templated ID
types yet, but I'm introducing one in a follow-up PR that needs this
capability.
This commit is contained in:
Geoff Romer
2026-05-07 00:13:52 +00:00
committed by GitHub
parent db24042fe5
commit daebbf32fa
10 changed files with 236 additions and 218 deletions
+6 -16
View File
@@ -406,25 +406,15 @@ struct Worklist {
CARBON_FATAL("Unexpected instruction operand kind {0}", typeid(T).name());
}
using AddFnT = auto(Worklist& worklist, int32_t arg) -> void;
// Returns the arg handler for an `IdKind`.
template <typename... Types>
static auto GetAddFn(TypeEnum<Types...> id_kind) -> AddFnT* {
static constexpr std::array<AddFnT*, IdKind::NumValues> Table = {
[](Worklist& worklist, int32_t arg) {
worklist.Add(Inst::FromRaw<Types>(arg));
}...,
// Invalid and None handling (ordering-sensitive).
[](auto...) { CARBON_FATAL("Unexpected invalid IdKind"); },
[](auto...) {},
};
return Table[id_kind.ToIndex()];
auto Add(IdAndKind::InvalidType /*invalid*/) -> void {
CARBON_FATAL("Unexpected invalid IdKind");
}
auto Add(IdAndKind::NoneType /*none*/) -> void {}
// Add an instruction argument to the contents of the current instruction.
auto AddWithKind(Inst::ArgAndKind arg) -> void {
GetAddFn(arg.kind())(*this, arg.value());
auto AddWithKind(IdAndKind arg) -> void {
arg.Dispatch<void>([this](auto id) { Add(id); });
}
// Ensure all the instructions on the todo list have fingerprints. To avoid a