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

Code before:
  if (bind_name.name_id == SemIR::NameId::PeriodSelf) {
    name_phase = Phase::PeriodSelfSymbolic;
  } else if (!bind_name.bind_index().has_value()) {
    name_phase = Phase::Concrete;
  } else if (bind_name.is_template) {
    name_phase = Phase::TemplateSymbolic;
  } else {
    name_phase = Phase::CheckedSymbolic;
  }
  *phase = LatestPhase(*phase, name_phase);
  return eval_context.entity_names().MakeCanonical(entity_name_id);
}

// Replaces the specified field of the given typed instruction with its constant
// value, if it has constant phase. Returns true on success, false if the value
// has runtime phase.
template <typename InstT, typename FieldIdT>
static auto ReplaceFieldWithConstantValue(EvalContext& eval_context,
                                          InstT* inst, FieldIdT InstT::* field,
                                          Phase* phase) -> bool {
  auto unwrapped = GetConstantValue(eval_context, inst->*field, phase);
  if (!unwrapped.has_value() && (inst->*field).has_value()) {
    return false;
  }
  inst->*field = unwrapped;
  return *phase < Phase::Runtime;
}

// Function template that can be called with an argument of type `T`. Used below
// to detect which overloads of `GetConstantValue` exist.
template <typename T>
static void Accept(T /*arg*/) {}

// Determines whether a `GetConstantValue` overload exists for a given ID type.
// Note that we do not check whether `GetConstantValue` is *callable* with a
// given ID type, because that would use the `InstId` overload for
// `AbsoluteInstId` and similar wrapper types, which should be left alone.
template <typename IdT>
static constexpr bool HasGetConstantValueOverload = requires {
  Accept<auto (*)(EvalContext&, IdT, Phase*)->IdT>(GetConstantValue);
};

using ArgHandlerFnT = auto(EvalContext& context, int32_t arg, Phase* phase)
    -> int32_t;

// Returns the arg handler for an `IdKind`.
template <typename... Types>
static auto GetArgHandlerFn(TypeEnum<Types...> id_kind) -> ArgHandlerFnT* {
  static constexpr std::array<ArgHandlerFnT*, SemIR::IdKind::NumValues> Table =
      {
          [](EvalContext& eval_context, int32_t arg, Phase* phase) -> int32_t {

Review comment (suggestion):
FWIW, I'd personally prefer something like "IsRuntimeOrError" over just a straight comparison, for readability.

Code after:
                             SemIR::EntityNameId entity_name_id, Phase* phase)
    -> SemIR::EntityNameId {
  const auto& bind_name = eval_context.entity_names().Get(entity_name_id);
  Phase name_phase;
  if (bind_name.name_id == SemIR::NameId::PeriodSelf) {
    name_phase = Phase::PeriodSelfSymbolic;
  } else if (!bind_name.bind_index().has_value()) {
    name_phase = Phase::Concrete;
  } else if (bind_name.is_template) {
    name_phase = Phase::TemplateSymbolic;
  } else {
    name_phase = Phase::CheckedSymbolic;
  }
  *phase = LatestPhase(*phase, name_phase);
  return eval_context.entity_names().MakeCanonical(entity_name_id);
}

// Replaces the specified field of the given typed instruction with its constant
// value, if it has constant phase. Returns true on success, false if the value
// has runtime phase.
template <typename InstT, typename FieldIdT>
static auto ReplaceFieldWithConstantValue(EvalContext& eval_context,
                                          InstT* inst, FieldIdT InstT::* field,
                                          Phase* phase) -> bool {
  auto unwrapped = GetConstantValue(eval_context, inst->*field, phase);
  if (!unwrapped.has_value() && (inst->*field).has_value()) {
    return false;
  }
  inst->*field = unwrapped;
  return IsConstantOrError(*phase);
}

// Function template that can be called with an argument of type `T`. Used below
// to detect which overloads of `GetConstantValue` exist.
template <typename T>
static void Accept(T /*arg*/) {}

// Determines whether a `GetConstantValue` overload exists for a given ID type.
// Note that we do not check whether `GetConstantValue` is *callable* with a
// given ID type, because that would use the `InstId` overload for
// `AbsoluteInstId` and similar wrapper types, which should be left alone.
template <typename IdT>
static constexpr bool HasGetConstantValueOverload = requires {
  Accept<auto (*)(EvalContext&, IdT, Phase*)->IdT>(GetConstantValue);
};

using ArgHandlerFnT = auto(EvalContext& context, int32_t arg, Phase* phase)
    -> int32_t;

// Returns the arg handler for an `IdKind`.
template <typename... Types>