From 30562826b8f0894e7103f8143b98ceeddb6d0bf8 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 7 Jan 2026 16:41:05 -0500 Subject: [PATCH] Add Inst::IsOneOf to check if an inst is one of a few kinds (#6523) Adds Inst::IsOneOf which takes a variadic generic parameter pack of kinds to check against. Also add forwarding functions to TypeStore and InstStore. Convert uses of the regex `Is<.*\|\|` to IsOneOf. This is based on #6522 --- toolchain/check/convert.cpp | 8 ++++---- toolchain/check/generic.cpp | 3 +-- toolchain/check/impl_lookup.cpp | 4 ++-- toolchain/check/import_ref.cpp | 3 +-- toolchain/lower/handle_aggregates.cpp | 5 ++--- toolchain/sem_ir/builtin_function_kind.cpp | 3 +-- toolchain/sem_ir/inst.h | 13 +++++++++++++ toolchain/sem_ir/type.h | 7 +++++++ 8 files changed, 31 insertions(+), 15 deletions(-) diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 00aea12a2739..211d17ede321 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -998,8 +998,8 @@ static auto PerformBuiltinConversion( if (auto foundation_type_id = context.types().GetTransitiveAdaptedType(value_type_id); foundation_type_id != value_type_id && - (context.types().Is(foundation_type_id) || - context.types().Is(foundation_type_id))) { + context.types().IsOneOf( + foundation_type_id)) { auto foundation_value_id = AddInst( context, loc_id, {.type_id = foundation_type_id, .source_id = value_id}); @@ -1264,8 +1264,8 @@ static auto PerformBuiltinConversion( // other facet values, as long as they satisfy the required interfaces of the // target `FacetType`. if (sem_ir.types().Is(target.type_id) && - (sem_ir.types().Is(value_type_id) || - sem_ir.types().Is(value_type_id))) { + sem_ir.types().IsOneOf( + value_type_id)) { // TODO: Runtime facet values should be allowed to convert based on their // FacetTypes, but we assume constant values for impl lookup at the moment. if (!context.constant_values().Get(value_id).is_constant()) { diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index f64e0f2db1c0..e9b20cd1a37e 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -149,8 +149,7 @@ class RebuildGenericConstantInEvalBlockCallbacks : public SubstInstCallbacks { auto ReuseUnchanged(SemIR::InstId orig_inst_id) -> SemIR::InstId override { auto inst = context().insts().Get(orig_inst_id); CARBON_CHECK( - inst.Is() || - inst.Is(), + (inst.IsOneOf()), "Instruction {0} has symbolic constant value but no symbolic operands", inst); diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index cded3192a694..ae270de6be0d 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -578,8 +578,8 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, context.insts() .Get(context.constant_values().GetInstId(query_self_const_id)) .type_id(); - CARBON_CHECK(context.types().Is(query_self_type_id) || - context.types().Is(query_self_type_id)); + CARBON_CHECK((context.types().IsOneOf( + query_self_type_id))); // The query facet type value is indeed a facet type. CARBON_CHECK(context.insts().Is( context.constant_values().GetInstId(query_facet_type_const_id))); diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index af910aebc812..173f4b6f497a 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -865,8 +865,7 @@ static auto GetLocalConstantId(ImportRefResolver& resolver, auto import_decl_inst_id = resolver.import_generics().Get(generic_id).decl_id; auto import_decl_inst = resolver.import_insts().GetWithAttachedType(import_decl_inst_id); - if (import_decl_inst.Is() || - import_decl_inst.Is()) { + if (import_decl_inst.IsOneOf()) { // For these decl types, the imported entity can be found via the // declaration's operands. return GetLocalConstantId(resolver, import_decl_inst_id); diff --git a/toolchain/lower/handle_aggregates.cpp b/toolchain/lower/handle_aggregates.cpp index 45a98a13367a..67cc799ca7ab 100644 --- a/toolchain/lower/handle_aggregates.cpp +++ b/toolchain/lower/handle_aggregates.cpp @@ -45,9 +45,8 @@ static auto GetElementIndex(FunctionContext::TypeInFile type, // For now, struct and tuple types map directly into LLVM struct types with // identical field numbering. - CARBON_CHECK( - type_inst.Is() || type_inst.Is(), - "Indexing unexpected aggregate type {0}", type_inst); + CARBON_CHECK((type_inst.IsOneOf()), + "Indexing unexpected aggregate type {0}", type_inst); return idx.index; } diff --git a/toolchain/sem_ir/builtin_function_kind.cpp b/toolchain/sem_ir/builtin_function_kind.cpp index b1ea9b8ad064..59ba4908cedc 100644 --- a/toolchain/sem_ir/builtin_function_kind.cpp +++ b/toolchain/sem_ir/builtin_function_kind.cpp @@ -758,8 +758,7 @@ static auto IsLiteralType(const File& sem_ir, TypeId type_id) -> bool { // Unwrap adapters. type_id = sem_ir.types().GetTransitiveAdaptedType(type_id); auto type_inst_id = sem_ir.types().GetAsInst(type_id); - return type_inst_id.Is() || - type_inst_id.Is(); + return type_inst_id.IsOneOf(); } // Determines whether a builtin call involves an integer or floating-point diff --git a/toolchain/sem_ir/inst.h b/toolchain/sem_ir/inst.h index 7e42a28532bf..2cbe14d88928 100644 --- a/toolchain/sem_ir/inst.h +++ b/toolchain/sem_ir/inst.h @@ -259,6 +259,13 @@ class Inst : public Printable { return Internal::InstLikeTypeInfo::IsKind(kind()); } + // Returns whether this instruction has one of the specified types. + template + requires(... && Internal::InstLikeType) + auto IsOneOf() const -> bool { + return (... || Internal::InstLikeTypeInfo::IsKind(kind())); + } + // Casts this instruction to the given typed instruction, which must match the // instruction's kind, and returns the typed instruction. template @@ -504,6 +511,12 @@ class InstStore { return Get(inst_id).Is(); } + // Returns whether the requested instruction is one of the specified types. + template + auto IsOneOf(InstId inst_id) const -> bool { + return Get(inst_id).Is(); + } + // Returns the requested instruction, which is known to have the specified // type. template diff --git a/toolchain/sem_ir/type.h b/toolchain/sem_ir/type.h index f1cee6ecbe82..e147ff49fed7 100644 --- a/toolchain/sem_ir/type.h +++ b/toolchain/sem_ir/type.h @@ -112,6 +112,13 @@ class TypeStore : public Yaml::Printable { return GetAsInst(type_id).Is(); } + // Returns whether one of the specified kinds of instruction was used to + // define the type. + template + auto IsOneOf(TypeId type_id) const -> bool { + return GetAsInst(type_id).IsOneOf(); + } + // Returns the instruction used to define the specified type, which is known // to be a particular kind of instruction. template