Repository: carbon-language/carbon-lang
File: toolchain/sem_ir/stringify_type.cpp (C++)

Code before:
    }

    auto untyped_inst = sem_ir.insts().Get(step.inst_id);
    CARBON_KIND_SWITCH(untyped_inst) {
      case SemIR::AutoType::Kind:
      case SemIR::BoolType::Kind:
      case SemIR::BoundMethodType::Kind:
      case SemIR::ErrorInst::Kind:
      case SemIR::IntLiteralType::Kind:
      case SemIR::LegacyFloatType::Kind:
      case SemIR::NamespaceType::Kind:
      case SemIR::SpecificFunctionType::Kind:
      case SemIR::StringType::Kind:
      case SemIR::TypeType::Kind:
      case SemIR::VtableType::Kind:
      case SemIR::WitnessType::Kind: {
        // Builtin instructions use their IR name as a label.
        out << untyped_inst.kind().ir_name();
        break;
      }
      case CARBON_KIND(ArrayType inst): {
        out << "[";
        step_stack.PushString("]");
        step_stack.PushArrayBound(inst.bound_id);
        step_stack.PushString("; ");
        step_stack.PushInstId(sem_ir.types().GetInstId(inst.element_type_id));
        break;
      }
      case CARBON_KIND(AssociatedEntityType inst): {
        out << "<associated ";
        step_stack.PushString(">");
        step_stack.PushInstId(sem_ir.types().GetInstId(inst.interface_type_id));
        step_stack.PushString(" in ");
        step_stack.PushInstId(sem_ir.types().GetInstId(inst.entity_type_id));
        break;
      }
      case BindAlias::Kind:
      case BindSymbolicName::Kind:
      case ExportDecl::Kind: {
        auto name_id =
            untyped_inst.As<AnyBindNameOrExportDecl>().entity_name_id;
        out << sem_ir.names().GetFormatted(
            sem_ir.entity_names().Get(name_id).name_id);
        break;
      }
      case CARBON_KIND(ClassType inst): {
        const auto& class_info = sem_ir.classes().Get(inst.class_id);
        out << sem_ir.names().GetFormatted(class_info.name_id);
        step_stack.PushSpecificId(class_info, inst.specific_id);
        break;
      }

Review comment (suggestion):
We seem to be doing this a lot; maybe we should add a `PushTypeId` for this.

Code after:
      continue;
    }
    CARBON_CHECK(step.kind == StepStack::Inst);
    if (!step.inst_id.is_valid()) {
      out << "<invalid type>";
      continue;
    }

    auto untyped_inst = sem_ir.insts().Get(step.inst_id);
    CARBON_KIND_SWITCH(untyped_inst) {
      case SemIR::AutoType::Kind:
      case SemIR::BoolType::Kind:
      case SemIR::BoundMethodType::Kind:
      case SemIR::ErrorInst::Kind:
      case SemIR::IntLiteralType::Kind:
      case SemIR::LegacyFloatType::Kind:
      case SemIR::NamespaceType::Kind:
      case SemIR::SpecificFunctionType::Kind:
      case SemIR::StringType::Kind:
      case SemIR::TypeType::Kind:
      case SemIR::VtableType::Kind:
      case SemIR::WitnessType::Kind: {
        // Builtin instructions use their IR name as a label.
        out << untyped_inst.kind().ir_name();
        break;
      }
      case CARBON_KIND(ArrayType inst): {
        out << "[";
        step_stack.PushString("]");
        step_stack.PushArrayBound(inst.bound_id);
        step_stack.PushString("; ");
        step_stack.PushTypeId(inst.element_type_id);
        break;
      }
      case CARBON_KIND(AssociatedEntityType inst): {
        out << "<associated ";
        step_stack.PushString(">");
        step_stack.PushTypeId(inst.interface_type_id);
        step_stack.PushString(" in ");
        step_stack.PushTypeId(inst.entity_type_id);
        break;
      }
      case BindAlias::Kind:
      case BindSymbolicName::Kind:
      case ExportDecl::Kind: {
        auto name_id =
            untyped_inst.As<AnyBindNameOrExportDecl>().entity_name_id;
        out << sem_ir.names().GetFormatted(
            sem_ir.entity_names().Get(name_id).name_id);
        break;
      }