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

Code before:
struct InstId : public IdBase<InstId> {
  static constexpr llvm::StringLiteral Label = "inst";
  using ValueType = Inst;

  // Represents the result of a name lookup that is temporarily disallowed
  // because the name is currently being initialized.
  static const InstId InitTombstone;

  using IdBase::IdBase;

  auto Print(llvm::raw_ostream& out) const -> void;
};

constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 1);

// And InstId whose value is a type. The fact it's a type is CHECKed on
// construction, and this allows that check to be represented in the type
// system.
struct TypeInstId : public InstId {
  explicit TypeInstId(File& sem_ir, InstId id);

  // Ergonomic helper for `Check::Context`, which is not visible from SemIR.
  template <class Context>
  explicit TypeInstId(Context& context, InstId id)
      : TypeInstId(context.sem_ir(), id) {}

  using InstId::InstId;

  static const TypeInstId None;

  static constexpr auto UnsafeMake(InstId id) -> TypeInstId {
    return TypeInstId(UnsafeCtor(), id);
  }

 private:
  struct UnsafeCtor {};
  explicit constexpr TypeInstId(UnsafeCtor /*unsafe*/, InstId id)
      : InstId(id) {}
};

constexpr TypeInstId TypeInstId::None = TypeInstId::UnsafeMake(InstId::None);

// An ID of an instruction that is referenced absolutely by another instruction.
// This should only be used as the type of a field within a typed instruction
// class.
//
// When a typed instruction has a field of this type, that field represents an
// absolute reference to another instruction that typically resides in a
// different entity. This behaves in most respects like an InstId field, but
// substitution into the typed instruction leaves the field unchanged rather
// than substituting into it.

Review comment (suggestion):
I think these are unused now. (And the first one seems to not be defined.)
```suggestion
```

Code after:
struct InstId : public IdBase<InstId> {
  static constexpr llvm::StringLiteral Label = "inst";
  using ValueType = Inst;

  // Represents the result of a name lookup that is temporarily disallowed
  // because the name is currently being initialized.
  static const InstId InitTombstone;

  using IdBase::IdBase;

  auto Print(llvm::raw_ostream& out) const -> void;
};

constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 1);

// And InstId whose value is a type. The fact it's a type is CHECKed on
// construction, and this allows that check to be represented in the type
// system.
struct TypeInstId : public InstId {
  static const TypeInstId None;

  using InstId::InstId;

  static constexpr auto UnsafeMake(InstId id) -> TypeInstId {
    return TypeInstId(UnsafeCtor(), id);
  }

 private:
  struct UnsafeCtor {};
  explicit constexpr TypeInstId(UnsafeCtor /*unsafe*/, InstId id)
      : InstId(id) {}
};

constexpr TypeInstId TypeInstId::None = TypeInstId::UnsafeMake(InstId::None);

// An ID of an instruction that is referenced absolutely by another instruction.
// This should only be used as the type of a field within a typed instruction
// class.
//
// When a typed instruction has a field of this type, that field represents an
// absolute reference to another instruction that typically resides in a
// different entity. This behaves in most respects like an InstId field, but
// substitution into the typed instruction leaves the field unchanged rather
// than substituting into it.
class AbsoluteInstId : public InstId {
 public:
  // Support implicit conversion from InstId so that InstId and AbsoluteInstId
  // have the same interface.
  // NOLINTNEXTLINE(google-explicit-constructor)
  constexpr AbsoluteInstId(InstId inst_id) : InstId(inst_id) {}