Repository: carbon-language/carbon-lang
File: toolchain/check/type_structure.cpp (C++)

Code before:
    // the queue works from the back.
    Push(interface_constraint);

    auto maybe_self_type_id = TryGetInstIdAsTypeId(self_inst_id);
    if (std::holds_alternative<SemIR::TypeId>(maybe_self_type_id)) {
      auto self_type_id = std::get<SemIR::TypeId>(maybe_self_type_id);
      CARBON_CHECK(self_type_id != SemIR::TypeId::None);
      Push(self_type_id);
    } else {
      CARBON_CHECK(std::holds_alternative<SymbolicType>(maybe_self_type_id));
      Push(SymbolicType());
    }
    BuildTypeStructure();

    return TypeStructure(std::exchange(structure_, {}),
                         first_symbolic_distance_);
  }

 private:
  auto BuildTypeStructure() -> void {
    while (!work_list_.empty()) {
      auto next = work_list_.back();
      work_list_.pop_back();

      if (std::holds_alternative<CloseType>(next)) {
        auto close_type = std::get<CloseType>(next);
        switch (close_type.closing) {
          case CloseOnly:
            break;
          case CloseWithConcrete:
            ++position_;
            structure_.push_back(TypeStructure::Structural::Concrete);
            break;
          case CloseWithSymbolic:
            SetFirstSymbolic(position_);
            ++position_;
            structure_.push_back(TypeStructure::Structural::Symbolic);
            break;
        }
        ++position_;  // Closing of type.
        structure_.push_back(TypeStructure::Structural::ConcreteCloseParen);
        continue;
      }

      if (std::holds_alternative<SemIR::SpecificInterface>(next)) {
        const auto& interface = std::get<SemIR::SpecificInterface>(next);
        auto args = GetSpecificArgs(interface.specific_id);
        ++position_;  // Opening of type.
        if (args.empty()) {
          structure_.push_back(TypeStructure::Structural::Concrete);
        } else {

Review comment (suggestion):
This can be done more compactly:
```suggestion
      if (auto* close_type = std::get_if<CloseType>(&next)) {
```

Code after:
    CARBON_CHECK(work_list_.empty());

    first_symbolic_distance_ = TypeStructure::InfiniteDistance;
    structure_.clear();

    // The self type comes first in the type structure, so we push it last, as
    // the queue works from the back.
    Push(interface_constraint);
    PushInstId(self_inst_id);
    BuildTypeStructure();

    return TypeStructure(std::exchange(structure_, {}),
                         first_symbolic_distance_);
  }

 private:
  auto BuildTypeStructure() -> void {
    while (!work_list_.empty()) {
      auto next = work_list_.back();
      work_list_.pop_back();

      if (std::holds_alternative<CloseType>(next)) {
        AppendStructural(TypeStructure::Structural::ConcreteCloseParen);
        continue;
      }

      if (const auto* interface =
              std::get_if<SemIR::SpecificInterface>(&next)) {
        auto args = GetSpecificArgs(interface->specific_id);
        if (args.empty()) {
          AppendStructural(TypeStructure::Structural::Concrete);
        } else {
          AppendStructural(TypeStructure::Structural::ConcreteOpenParen);
          Push(CloseType());
          PushArgs(args);
        }
        continue;
      }

      if (std::holds_alternative<SymbolicType>(next)) {
        AppendStructural(TypeStructure::Structural::Symbolic);
        continue;
      }

      if (std::holds_alternative<NonTypeValue>(next)) {
        // TODO: Include the value's type into the structure, with the type
        // coming first and paired together with the value, like:
        // `{TypeWithPossibleNestedTypes, Concrete}`.
        // We might want a different bracket marker than ConcreteOpenParen for
        // this so that it can look different in the type structure when dumped.
        AppendStructural(TypeStructure::Structural::Concrete);