Răsfoiți Sursa

Update TypeIterator to use CARBON_KIND_SWITCH (#6105)

Also clean up unnecessary `SemIR::` use in these files.
Jon Ross-Perkins 7 luni în urmă
părinte
comite
70cde77f0e
2 a modificat fișierele cu 180 adăugiri și 181 ștergeri
  1. 151 153
      toolchain/sem_ir/type_iterator.cpp
  2. 29 28
      toolchain/sem_ir/type_iterator.h

+ 151 - 153
toolchain/sem_ir/type_iterator.cpp

@@ -19,174 +19,172 @@ auto TypeIterator::Next() -> Step {
     auto next = work_list_.back();
     work_list_.pop_back();
 
-    // TODO: Consider using a CARBON_KIND_SWITCH on `next` here after
-    // https://github.com/carbon-language/carbon-lang/pull/5433 arrives, instead
-    // of a bunch of `if` conditions.
-
-    if (std::holds_alternative<EndType>(next)) {
-      return Step::End();
-    }
-
-    if (const auto* interface = std::get_if<SemIR::SpecificInterface>(&next)) {
-      auto args = GetSpecificArgs(interface->specific_id);
-      if (args.empty()) {
-        return Step::InterfaceStartOnly{
-            {.interface_id = interface->interface_id}};
-      } else {
-        Push(EndType());
-        PushArgs(args);
-        return Step::InterfaceStart{.interface_id = interface->interface_id};
+    CARBON_KIND_SWITCH(next) {
+      case CARBON_KIND(ConcreteNonTypeValue value): {
+        return Step::ConcreteValue{.inst_id = value.inst_id};
+      }
+      case CARBON_KIND(EndType _): {
+        return Step::End();
+      }
+      case CARBON_KIND(SpecificInterface interface): {
+        auto args = GetSpecificArgs(interface.specific_id);
+        if (args.empty()) {
+          return Step::InterfaceStartOnly{
+              {.interface_id = interface.interface_id}};
+        } else {
+          Push(EndType());
+          PushArgs(args);
+          return Step::InterfaceStart{.interface_id = interface.interface_id};
+        }
+      }
+      case CARBON_KIND(StructFieldName value): {
+        return Step::StructFieldName{.name_id = value.name_id};
+      }
+      case CARBON_KIND(SymbolicNonTypeValue value): {
+        return Step::SymbolicValue{.inst_id = value.inst_id};
+      }
+      case CARBON_KIND(SymbolicType symbolic): {
+        return Step::SymbolicType{.facet_type_id = symbolic.facet_type_id};
+      }
+      case CARBON_KIND(TypeId type_id): {
+        if (auto step = ProcessTypeId(type_id)) {
+          return *step;
+        }
       }
     }
+  }
 
-    if (const auto* symbolic = std::get_if<SymbolicType>(&next)) {
-      return Step::SymbolicType{.facet_type_id = symbolic->facet_type_id};
-    }
+  return Step::Done();
+}
 
-    if (const auto* value = std::get_if<ConcreteNonTypeValue>(&next)) {
-      return Step::ConcreteValue{.inst_id = value->inst_id};
-    }
+auto TypeIterator::ProcessTypeId(TypeId type_id) -> std::optional<Step> {
+  auto inst_id = sem_ir_->types().GetInstId(type_id);
+  auto inst = sem_ir_->insts().Get(inst_id);
+  CARBON_KIND_SWITCH(inst) {
+      // ==== Symbolic types ====
 
-    if (const auto* value = std::get_if<SymbolicNonTypeValue>(&next)) {
-      return Step::SymbolicValue{.inst_id = value->inst_id};
+    case BindSymbolicName::Kind:
+    case SymbolicBindingPattern::Kind: {
+      return Step::SymbolicType{.facet_type_id = type_id};
     }
-
-    if (const auto* value = std::get_if<StructFieldName>(&next)) {
-      return Step::StructFieldName{.name_id = value->name_id};
+    case TypeOfInst::Kind: {
+      return Step::TemplateType();
     }
 
-    SemIR::TypeId type_id = std::get<SemIR::TypeId>(next);
-    auto inst_id = sem_ir_->types().GetInstId(type_id);
-    auto inst = sem_ir_->insts().Get(inst_id);
-    CARBON_KIND_SWITCH(inst) {
-        // ==== Symbolic types ====
-
-      case SemIR::BindSymbolicName::Kind:
-      case SemIR::SymbolicBindingPattern::Kind: {
-        return Step::SymbolicType{.facet_type_id = type_id};
-      }
-      case SemIR::TypeOfInst::Kind: {
-        return Step::TemplateType();
-      }
-
-      case CARBON_KIND(SemIR::FacetAccessType access): {
-        auto facet_type_id =
-            sem_ir_->insts().Get(access.facet_value_inst_id).type_id();
-        return Step::SymbolicType{.facet_type_id = facet_type_id};
-      }
+    case CARBON_KIND(FacetAccessType access): {
+      auto facet_type_id =
+          sem_ir_->insts().Get(access.facet_value_inst_id).type_id();
+      return Step::SymbolicType{.facet_type_id = facet_type_id};
+    }
 
-        // ==== Concrete types ====
-
-      case SemIR::AssociatedEntityType::Kind:
-      case SemIR::BoolType::Kind:
-      case SemIR::CharLiteralType::Kind:
-      case SemIR::FacetType::Kind:
-      case SemIR::FloatLiteralType::Kind:
-      case SemIR::FloatType::Kind:
-      case SemIR::FunctionType::Kind:
-      case SemIR::FunctionTypeWithSelfType::Kind:
-      case SemIR::GenericClassType::Kind:
-      case SemIR::GenericInterfaceType::Kind:
-      case SemIR::ImplWitnessAccess::Kind:
-      case SemIR::IntLiteralType::Kind:
-      case SemIR::NamespaceType::Kind:
-      case SemIR::TypeType::Kind:
-      case SemIR::WitnessType::Kind: {
-        return Step::ConcreteType{.type_id = type_id};
-      }
+      // ==== Concrete types ====
+
+    case AssociatedEntityType::Kind:
+    case BoolType::Kind:
+    case CharLiteralType::Kind:
+    case FacetType::Kind:
+    case FloatLiteralType::Kind:
+    case FloatType::Kind:
+    case FunctionType::Kind:
+    case FunctionTypeWithSelfType::Kind:
+    case GenericClassType::Kind:
+    case GenericInterfaceType::Kind:
+    case ImplWitnessAccess::Kind:
+    case IntLiteralType::Kind:
+    case NamespaceType::Kind:
+    case TypeType::Kind:
+    case WitnessType::Kind: {
+      return Step::ConcreteType{.type_id = type_id};
+    }
 
-      case CARBON_KIND(SemIR::IntType int_type): {
-        Push(EndType());
-        PushArgs({int_type.bit_width_id});
-        return Step::IntStart{.type_id = type_id};
-      }
+    case CARBON_KIND(IntType int_type): {
+      Push(EndType());
+      PushArgs({int_type.bit_width_id});
+      return Step::IntStart{.type_id = type_id};
+    }
 
-        // ==== Aggregate types ====
+      // ==== Aggregate types ====
 
-      case CARBON_KIND(SemIR::ArrayType array_type): {
-        Push(EndType());
-        PushInstId(array_type.element_type_inst_id);
-        PushInstId(array_type.bound_id);
-        return Step::ArrayStart{.type_id = type_id};
-      }
-      case CARBON_KIND(SemIR::ClassType class_type): {
-        auto args = GetSpecificArgs(class_type.specific_id);
-        if (args.empty()) {
-          return Step::ClassStartOnly{
-              {.class_id = class_type.class_id, .type_id = type_id}};
-        } else {
-          Push(EndType());
-          PushArgs(args);
-          return Step::ClassStart{.class_id = class_type.class_id,
-                                  .type_id = type_id};
-        }
-      }
-      case CARBON_KIND(SemIR::ConstType const_type): {
-        Push(EndType());
-        PushInstId(const_type.inner_id);
-        return Step::ConstStart();
-      }
-      case CARBON_KIND(SemIR::ImplWitnessAssociatedConstant assoc): {
-        Push(assoc.type_id);
-        break;
-      }
-      case CARBON_KIND(SemIR::MaybeUnformedType maybe_unformed_type): {
+    case CARBON_KIND(ArrayType array_type): {
+      Push(EndType());
+      PushInstId(array_type.element_type_inst_id);
+      PushInstId(array_type.bound_id);
+      return Step::ArrayStart{.type_id = type_id};
+    }
+    case CARBON_KIND(ClassType class_type): {
+      auto args = GetSpecificArgs(class_type.specific_id);
+      if (args.empty()) {
+        return Step::ClassStartOnly{
+            {.class_id = class_type.class_id, .type_id = type_id}};
+      } else {
         Push(EndType());
-        PushInstId(maybe_unformed_type.inner_id);
-        return Step::MaybeUnformedStart();
+        PushArgs(args);
+        return Step::ClassStart{.class_id = class_type.class_id,
+                                .type_id = type_id};
       }
-      case CARBON_KIND(SemIR::PartialType partial_type): {
+    }
+    case CARBON_KIND(ConstType const_type): {
+      Push(EndType());
+      PushInstId(const_type.inner_id);
+      return Step::ConstStart();
+    }
+    case CARBON_KIND(ImplWitnessAssociatedConstant assoc): {
+      Push(assoc.type_id);
+      return std::nullopt;
+    }
+    case CARBON_KIND(MaybeUnformedType maybe_unformed_type): {
+      Push(EndType());
+      PushInstId(maybe_unformed_type.inner_id);
+      return Step::MaybeUnformedStart();
+    }
+    case CARBON_KIND(PartialType partial_type): {
+      Push(EndType());
+      PushInstId(partial_type.inner_id);
+      return Step::PartialStart();
+    }
+    case CARBON_KIND(PointerType pointer_type): {
+      Push(EndType());
+      PushInstId(pointer_type.pointee_id);
+      return Step::PointerStart();
+    }
+    case CARBON_KIND(TupleType tuple_type): {
+      auto inner_types =
+          sem_ir_->inst_blocks().Get(tuple_type.type_elements_id);
+      if (inner_types.empty()) {
+        return Step::TupleStartOnly{{.type_id = type_id}};
+      } else {
         Push(EndType());
-        PushInstId(partial_type.inner_id);
-        return Step::PartialStart();
+        PushArgs(sem_ir_->inst_blocks().Get(tuple_type.type_elements_id));
+        return Step::TupleStart{.type_id = type_id};
       }
-      case CARBON_KIND(SemIR::PointerType pointer_type): {
+    }
+    case CARBON_KIND(StructType struct_type): {
+      auto fields = sem_ir_->struct_type_fields().Get(struct_type.fields_id);
+      if (fields.empty()) {
+        return Step::StructStartOnly{{.type_id = type_id}};
+      } else {
         Push(EndType());
-        PushInstId(pointer_type.pointee_id);
-        return Step::PointerStart();
-      }
-      case CARBON_KIND(SemIR::TupleType tuple_type): {
-        auto inner_types =
-            sem_ir_->inst_blocks().Get(tuple_type.type_elements_id);
-        if (inner_types.empty()) {
-          return Step::TupleStartOnly{{.type_id = type_id}};
-        } else {
-          Push(EndType());
-          PushArgs(sem_ir_->inst_blocks().Get(tuple_type.type_elements_id));
-          return Step::TupleStart{.type_id = type_id};
-        }
-      }
-      case CARBON_KIND(SemIR::StructType struct_type): {
-        auto fields = sem_ir_->struct_type_fields().Get(struct_type.fields_id);
-        if (fields.empty()) {
-          return Step::StructStartOnly{{.type_id = type_id}};
-        } else {
-          Push(EndType());
-          for (const auto& field : llvm::reverse(fields)) {
-            Push(StructFieldName{.name_id = field.name_id});
-            PushInstId(field.type_inst_id);
-          }
-          return Step::StructStart{.type_id = type_id};
+        for (const auto& field : llvm::reverse(fields)) {
+          Push(StructFieldName{.name_id = field.name_id});
+          PushInstId(field.type_inst_id);
         }
+        return Step::StructStart{.type_id = type_id};
       }
+    }
 
-      case SemIR::ErrorInst::Kind:
-        return Step::Error();
+    case ErrorInst::Kind:
+      return Step::Error();
 
-      default:
-        // TODO: Rearrange this so that missing instruction kinds are detected
-        // at compile-time not runtime.
-        CARBON_FATAL("Unhandled type instruction {0}", inst_id);
-    }
+    default:
+      // TODO: Rearrange this so that missing instruction kinds are detected
+      // at compile-time not runtime.
+      CARBON_FATAL("Unhandled type instruction {0}", inst_id);
   }
-
-  return Step::Done();
 }
 
-auto TypeIterator::TryGetInstIdAsTypeId(SemIR::InstId inst_id) const
-    -> std::variant<SemIR::TypeId, SymbolicType> {
-  if (auto facet_value =
-          sem_ir_->insts().TryGetAs<SemIR::FacetValue>(inst_id)) {
+auto TypeIterator::TryGetInstIdAsTypeId(InstId inst_id) const
+    -> std::variant<TypeId, SymbolicType> {
+  if (auto facet_value = sem_ir_->insts().TryGetAs<FacetValue>(inst_id)) {
     inst_id = facet_value->type_inst_id;
   }
 
@@ -207,19 +205,19 @@ auto TypeIterator::TryGetInstIdAsTypeId(SemIR::InstId inst_id) const
   // FacetType it does so through a FacetAccessType, which is of type TypeType
   // and thus does not match here.
   if (auto facet_type =
-          sem_ir_->types().TryGetAs<SemIR::FacetType>(type_id_of_inst_id)) {
+          sem_ir_->types().TryGetAs<FacetType>(type_id_of_inst_id)) {
     return SymbolicType{.facet_type_id = type_id_of_inst_id};
   }
   // Non-type values are concrete, only types are symbolic.
-  if (type_id_of_inst_id != SemIR::TypeType::TypeId) {
-    return SemIR::TypeId::None;
+  if (type_id_of_inst_id != TypeType::TypeId) {
+    return TypeId::None;
   }
   return sem_ir_->types().GetTypeIdForTypeInstId(inst_id);
 }
 
-auto TypeIterator::GetSpecificArgs(SemIR::SpecificId specific_id) const
-    -> llvm::ArrayRef<SemIR::InstId> {
-  if (specific_id == SemIR::SpecificId::None) {
+auto TypeIterator::GetSpecificArgs(SpecificId specific_id) const
+    -> llvm::ArrayRef<InstId> {
+  if (specific_id == SpecificId::None) {
     return {};
   }
   auto specific = sem_ir_->specifics().Get(specific_id);
@@ -227,7 +225,7 @@ auto TypeIterator::GetSpecificArgs(SemIR::SpecificId specific_id) const
 }
 
 // Push all arguments from the array into the work queue.
-auto TypeIterator::PushArgs(llvm::ArrayRef<SemIR::InstId> args) -> void {
+auto TypeIterator::PushArgs(llvm::ArrayRef<InstId> args) -> void {
   for (auto arg_id : llvm::reverse(args)) {
     PushInstId(arg_id);
   }
@@ -235,11 +233,11 @@ auto TypeIterator::PushArgs(llvm::ArrayRef<SemIR::InstId> args) -> void {
 
 // Push an instruction's type value into the work queue, or a marker if the
 // instruction has a symbolic value.
-auto TypeIterator::PushInstId(SemIR::InstId inst_id) -> void {
+auto TypeIterator::PushInstId(InstId inst_id) -> void {
   auto maybe_type_id = TryGetInstIdAsTypeId(inst_id);
   if (std::holds_alternative<SymbolicType>(maybe_type_id)) {
     Push(std::get<SymbolicType>(maybe_type_id));
-  } else if (auto type_id = std::get<SemIR::TypeId>(maybe_type_id);
+  } else if (auto type_id = std::get<TypeId>(maybe_type_id);
              type_id.has_value()) {
     Push(type_id);
   } else if (sem_ir_->constant_values().Get(inst_id).is_symbolic()) {

+ 29 - 28
toolchain/sem_ir/type_iterator.h

@@ -38,7 +38,7 @@ class TypeIterator {
   // Add a type value or facet value to be iterated over.
   //
   // The iterator will visit things in the reverse order that they are added.
-  auto Add(SemIR::InstId inst_id) -> void {
+  auto Add(InstId inst_id) -> void {
     auto type_id = sem_ir_->insts().Get(inst_id).type_id();
     CARBON_CHECK(sem_ir_->types().IsFacetType(type_id));
     PushInstId(inst_id);
@@ -47,7 +47,7 @@ class TypeIterator {
   // Add an interface to be iterated over.
   //
   // The iterator will visit things in the reverse order that they are added.
-  auto Add(SemIR::SpecificInterface interface) -> void { Push(interface); }
+  auto Add(SpecificInterface interface) -> void { Push(interface); }
 
   // Iterates and returns the next `Step`. Returns `Step::Done` when complete.
   auto Next() -> Step;
@@ -57,25 +57,27 @@ class TypeIterator {
   struct EndType {};
   // A work item to mark a symbolic type.
   struct SymbolicType {
-    SemIR::TypeId facet_type_id;
+    TypeId facet_type_id;
   };
   // A work item to mark a concrete non-type value.
   struct ConcreteNonTypeValue {
-    SemIR::InstId inst_id;
+    InstId inst_id;
   };
   // A work item to mark a symbolic non-type value.
   struct SymbolicNonTypeValue {
-    SemIR::InstId inst_id;
+    InstId inst_id;
   };
   // A work item to mark the name of a struct field.
   struct StructFieldName {
-    SemIR::NameId name_id;
+    NameId name_id;
   };
 
-  using WorkItem =
-      std::variant<SemIR::TypeId, SymbolicType, ConcreteNonTypeValue,
-                   SymbolicNonTypeValue, StructFieldName,
-                   SemIR::SpecificInterface, EndType>;
+  using WorkItem = std::variant<TypeId, SymbolicType, ConcreteNonTypeValue,
+                                SymbolicNonTypeValue, StructFieldName,
+                                SpecificInterface, EndType>;
+
+  // Processes `next` when it's a `TypeId`.
+  auto ProcessTypeId(TypeId type_id) -> std::optional<Step>;
 
   // Get the TypeId for an instruction that is not a facet value, otherwise
   // return SymbolicType to indicate the instruction is a symbolic facet value.
@@ -83,19 +85,18 @@ class TypeIterator {
   // If the instruction is not a type value, the return is TypeId::None.
   //
   // We reuse the `SymbolicType` work item here to give a nice return type.
-  auto TryGetInstIdAsTypeId(SemIR::InstId inst_id) const
-      -> std::variant<SemIR::TypeId, SymbolicType>;
+  auto TryGetInstIdAsTypeId(InstId inst_id) const
+      -> std::variant<TypeId, SymbolicType>;
 
   // Get the instructions in the specific's instruction block as an ArrayRef.
-  auto GetSpecificArgs(SemIR::SpecificId specific_id) const
-      -> llvm::ArrayRef<SemIR::InstId>;
+  auto GetSpecificArgs(SpecificId specific_id) const -> llvm::ArrayRef<InstId>;
 
   // Push all arguments from the array into the work queue.
-  auto PushArgs(llvm::ArrayRef<SemIR::InstId> args) -> void;
+  auto PushArgs(llvm::ArrayRef<InstId> args) -> void;
 
   // Push an instruction's type value into the work queue, or a marker if the
   // instruction has a symbolic value.
-  auto PushInstId(SemIR::InstId inst_id) -> void;
+  auto PushInstId(InstId inst_id) -> void;
 
   // Push the next step into the work queue.
   auto Push(WorkItem item) -> void;
@@ -112,28 +113,28 @@ class TypeIterator::Step {
 
   // Followed by generic parameters.
   struct ClassStart {
-    SemIR::ClassId class_id;
-    SemIR::TypeId type_id;
+    ClassId class_id;
+    TypeId type_id;
   };
   // Followed by its fields.
   struct StructStart {
-    SemIR::TypeId type_id;
+    TypeId type_id;
   };
   // Followed by its members.
   struct TupleStart {
-    SemIR::TypeId type_id;
+    TypeId type_id;
   };
   // Followed by generic parameters.
   struct InterfaceStart {
-    SemIR::InterfaceId interface_id;
+    InterfaceId interface_id;
   };
   // Followed by the bit width.
   struct IntStart {
-    SemIR::TypeId type_id;
+    TypeId type_id;
   };
   // Followed by the type and bound.
   struct ArrayStart {
-    SemIR::TypeId type_id;
+    TypeId type_id;
   };
   // Simple wrapped types, followed by the inner type.
   struct ConstStart {};
@@ -157,12 +158,12 @@ class TypeIterator::Step {
 
   // A type value.
   struct ConcreteType {
-    SemIR::TypeId type_id;
+    TypeId type_id;
   };
   // A symbolic type value, constrained by `facet_type_id`.
   struct SymbolicType {
     // Either a FacetType or the TypeType singleton.
-    SemIR::TypeId facet_type_id;
+    TypeId facet_type_id;
   };
   // A symbolic template type value.
   struct TemplateType {};
@@ -170,17 +171,17 @@ class TypeIterator::Step {
   // type.
   struct ConcreteValue {
     // An instruction that evaluates to the constant value.
-    SemIR::InstId inst_id;
+    InstId inst_id;
   };
   // A symbolic non-type value, which can be found as a generic parameter for a
   // type.
   struct SymbolicValue {
     // An instruction that evaluates to the constant value.
-    SemIR::InstId inst_id;
+    InstId inst_id;
   };
   // A struct field name. The field names contribute to the type of the struct.
   struct StructFieldName {
-    SemIR::NameId name_id;
+    NameId name_id;
   };
 
   // ===========================================================================