Repository: carbon-language/carbon-lang
File: toolchain/sem_ir/typed_insts.h (C/C++)

Code before:
//   listed in the `IdKind` type-enum, typically derived from `IdBase`.
//
// The field names here matter -- the fields must have the names specified
// above, when present. When converting to a `Inst`, the `kind` and `type_id`
// fields will become the kind and type associated with the type-erased
// instruction.
//
// Each type that describes a single kind of instructions provides a constant
// `Kind` that associates the type with a particular member of the `InstKind`
// enumeration. This `Kind` declaration also defines the instruction kind by
// calling `InstKind::Define` and specifying additional information about the
// instruction kind. This information is available through the member functions
// of the `InstKind` value declared in `inst_kind.h`, and includes the name used
// in textual IR and whether the instruction is a terminator instruction.
//
// Struct types can also be provided for categories of instructions with a
// common representation, to allow the common representation to be accessed
// conveniently. In this case, instead of providing a constant `Kind` member,
// the struct should have a constant `InstKind Kinds[];` member that lists the
// kinds of instructions in the category, and an `InstKind kind;` member that is
// used to identify the specific kind of the instruction. Separate struct types
// still need to be defined for each instruction kind in the category.

namespace Carbon::SemIR {

// A singleton type.
template <InstKind::RawEnumType KindT, TemplateString IrName>
struct SingletonTypeInst final {
  static constexpr auto Kind = InstKind::Make(KindT).Define<Parse::NoneNodeId>(
      InstKind::DefinitionInfo{.ir_name = IrName,
                               .is_type = InstIsType::Always,
                               .constant_kind = InstConstantKind::Always});
  static constexpr auto TypeInstId = MakeSingletonTypeInstId<Kind>();
  static constexpr SemIR::InstId InstId = TypeInstId;
  static constexpr auto ConstantId = ConstantId::ForConcreteConstant(InstId);
  static constexpr auto TypeId =
      TypeId::ForTypeConstant(ConstantId::ForConcreteConstant(TypeInstId));

  // Singleton types have a type of `TypeType`, except for `ErrorInst` which
  // uses itself.
  SemIR::TypeId type_id;
};

// An action that performs simple member access, `base.name`.
struct AccessMemberAction {
  static constexpr auto Kind =
      InstKind::AccessMemberAction.Define<Parse::NodeId>(
          {.ir_name = "access_member_action",
           .constant_kind = InstConstantKind::InstAction,
           .is_lowered = false});


Review comment (suggestion):
```suggestion
// A template for singleton types.
```

Code after:
//   listed in the `IdKind` type-enum, typically derived from `IdBase`.
//
// The field names here matter -- the fields must have the names specified
// above, when present. When converting to a `Inst`, the `kind` and `type_id`
// fields will become the kind and type associated with the type-erased
// instruction.
//
// Each type that describes a single kind of instructions provides a constant
// `Kind` that associates the type with a particular member of the `InstKind`
// enumeration. This `Kind` declaration also defines the instruction kind by
// calling `InstKind::Define` and specifying additional information about the
// instruction kind. This information is available through the member functions
// of the `InstKind` value declared in `inst_kind.h`, and includes the name used
// in textual IR and whether the instruction is a terminator instruction.
//
// Struct types can also be provided for categories of instructions with a
// common representation, to allow the common representation to be accessed
// conveniently. In this case, instead of providing a constant `Kind` member,
// the struct should have a constant `InstKind Kinds[];` member that lists the
// kinds of instructions in the category, and an `InstKind kind;` member that is
// used to identify the specific kind of the instruction. Separate struct types
// still need to be defined for each instruction kind in the category.

namespace Carbon::SemIR {

// A template for singleton types.
template <InstKind::RawEnumType KindT, TemplateString IrName>
struct SingletonTypeInst final {
  static constexpr auto Kind = InstKind::Make(KindT).Define<Parse::NoneNodeId>(
      InstKind::DefinitionInfo{.ir_name = IrName,
                               .is_type = InstIsType::Always,
                               .constant_kind = InstConstantKind::Always});
  static constexpr auto TypeInstId = MakeSingletonTypeInstId<Kind>();
  static constexpr SemIR::InstId InstId = TypeInstId;
  static constexpr auto ConstantId = ConstantId::ForConcreteConstant(InstId);
  static constexpr auto TypeId =
      TypeId::ForTypeConstant(ConstantId::ForConcreteConstant(TypeInstId));

  // Singleton types have a type of `TypeType`, except for `ErrorInst` which
  // uses itself.
  SemIR::TypeId type_id;
};

// An action that performs simple member access, `base.name`.
struct AccessMemberAction {
  static constexpr auto Kind =
      InstKind::AccessMemberAction.Define<Parse::NodeId>(
          {.ir_name = "access_member_action",
           .constant_kind = InstConstantKind::InstAction,
           .is_lowered = false});