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

Code before:
        auto fields = sem_ir.struct_type_fields().Get(inst.fields_id);
        if (fields.empty()) {
          out << "{}";
          break;
        }
        out << "{";
        step_stack.PushString("}");
        for (auto index : llvm::reverse(llvm::seq(fields.size()))) {
          const auto& field = fields[index];
          step_stack.PushTypeId(field.type_id);
          step_stack.PushString(": ");
          step_stack.PushNameId(field.name_id);
          step_stack.PushString(".");
          if (index > 0) {
            step_stack.PushString(", ");
          }
        }
        break;
      }
      case CARBON_KIND(StructValue inst): {
        auto field_values = sem_ir.inst_blocks().Get(inst.elements_id);
        if (field_values.empty()) {
          out << "{}";
          break;
        }
        auto struct_type = sem_ir.types().GetAs<StructType>(inst.type_id);
        auto fields = sem_ir.struct_type_fields().Get(struct_type.fields_id);
        if (fields.size() != field_values.size()) {
          out << "{<struct value type length mismatch>}";
          break;
        }
        out << "{";
        step_stack.PushString("}");
        for (auto index : llvm::reverse(llvm::seq(fields.size()))) {
          SemIR::InstId value_inst_id = field_values[index];
          step_stack.PushInstId(value_inst_id);
          step_stack.PushString(" = ");
          step_stack.PushNameId(fields[index].name_id);
          step_stack.PushString(".");
          if (index > 0) {
            step_stack.PushString(", ");
          }
        }
        break;
      }
      case CARBON_KIND(TupleType inst): {
        auto refs = sem_ir.type_blocks().Get(inst.elements_id);
        if (refs.empty()) {
          out << "()";
          break;
        }

Review comment (suggestion):
We build `StructValue`s of class type for class values too. We also build them for a few other types that "should be" class types -- for the values of `FunctionDecl`s, `ClassDecl`s, and `InterfaceDecl`s -- but those are all empty so don't get here.

I think we can handle the class type case with simply:
```suggestion
        auto struct_type = sem_ir.types().GetAs<StructType>(
            sem_ir.types().GetObjectRepr(inst.type_id));
```

Code after:
        auto fields = sem_ir.struct_type_fields().Get(inst.fields_id);
        if (fields.empty()) {
          out << "{}";
          break;
        }
        out << "{";
        step_stack.PushString("}");
        for (auto index : llvm::reverse(llvm::seq(fields.size()))) {
          const auto& field = fields[index];
          step_stack.PushTypeId(field.type_id);
          step_stack.PushString(": ");
          step_stack.PushNameId(field.name_id);
          step_stack.PushString(".");
          if (index > 0) {
            step_stack.PushString(", ");
          }
        }
        break;
      }
      case CARBON_KIND(StructValue inst): {
        auto field_values = sem_ir.inst_blocks().Get(inst.elements_id);
        if (field_values.empty()) {
          out << "{}";
          break;
        }
        auto struct_type = sem_ir.types().GetAs<StructType>(
            sem_ir.types().GetObjectRepr(inst.type_id));
        auto fields = sem_ir.struct_type_fields().Get(struct_type.fields_id);
        if (fields.size() != field_values.size()) {
          out << "{<struct value type length mismatch>}";
          break;
        }
        out << "{";
        step_stack.PushString("}");
        for (auto index : llvm::reverse(llvm::seq(fields.size()))) {
          SemIR::InstId value_inst_id = field_values[index];
          step_stack.PushInstId(value_inst_id);
          step_stack.PushString(" = ");
          step_stack.PushNameId(fields[index].name_id);
          step_stack.PushString(".");
          if (index > 0) {
            step_stack.PushString(", ");
          }
        }
        break;
      }
      case CARBON_KIND(TupleType inst): {
        auto refs = sem_ir.type_blocks().Get(inst.elements_id);
        if (refs.empty()) {
          out << "()";
          break;