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

Code before:
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::BranchIf>(FunctionExecContext& eval_context,
                                       SemIR::InstId /*inst_id*/,
                                       SemIR::Inst inst) -> SemIR::ConstantId {
  auto branch_if = inst.As<SemIR::BranchIf>();
  auto cond_id = CheckConcreteValue(eval_context, branch_if.cond_id);
  if (cond_id == SemIR::ErrorInst::InstId) {
    return SemIR::ErrorInst::ConstantId;
  }
  auto cond = eval_context.insts().GetAs<SemIR::BoolLiteral>(cond_id);
  if (cond.value == SemIR::BoolValue::True) {
    eval_context.BranchTo(branch_if.target_id);
  }
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::BranchWithArg>(FunctionExecContext& eval_context,
                                            SemIR::InstId /*inst_id*/,
                                            SemIR::Inst inst)
    -> SemIR::ConstantId {
  auto branch = inst.As<SemIR::BranchWithArg>();
  eval_context.SetLastBlockArg(
      {.block_id = branch.target_id,
       .arg_id = eval_context.GetConstantValue(branch.arg_id)});
  eval_context.BranchTo(branch.target_id);
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::Return>(FunctionExecContext& eval_context,
                                     SemIR::InstId /*inst_id*/,
                                     SemIR::Inst /*inst*/)
    -> SemIR::ConstantId {
  return MakeEmptyTupleResult(eval_context);
}

template <>
auto TryExecTypedInst<SemIR::ReturnExpr>(FunctionExecContext& eval_context,
                                         SemIR::InstId /*inst_id*/,
                                         SemIR::Inst inst)
    -> SemIR::ConstantId {
  auto return_expr = inst.As<SemIR::ReturnExpr>();
  return eval_context.GetConstantValue(return_expr.expr_id);
}

template <>
auto TryExecTypedInst<SemIR::ReturnSlot>(FunctionExecContext& eval_context,

Review comment (suggestion):
It took a bit to wrap my head around this because this is the last BranchWithArg, which a _future_ BlockArg_ (inst) is going to read. But the fn name sounds like it was the last BlockArg (inst), but it's the storage of the `BranchWithArg` (inst) that we've called `BlockArg`. I think splitting the BlockArg names as suggested above will fix this when it applies here though.


Code after:
template <>
auto TryExecTypedInst<SemIR::Branch>(FunctionExecContext& eval_context,
                                     SemIR::InstId /*inst_id*/,
                                     SemIR::Inst inst) -> SemIR::ConstantId {
  auto branch = inst.As<SemIR::Branch>();
  eval_context.BranchTo(branch.target_id);
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::BranchIf>(FunctionExecContext& eval_context,
                                       SemIR::InstId /*inst_id*/,
                                       SemIR::Inst inst) -> SemIR::ConstantId {
  auto branch_if = inst.As<SemIR::BranchIf>();
  auto cond_id = CheckConcreteValue(eval_context, branch_if.cond_id);
  if (cond_id == SemIR::ErrorInst::InstId) {
    return SemIR::ErrorInst::ConstantId;
  }
  auto cond = eval_context.insts().GetAs<SemIR::BoolLiteral>(cond_id);
  if (cond.value == SemIR::BoolValue::True) {
    eval_context.BranchTo(branch_if.target_id);
  }
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::BranchWithArg>(FunctionExecContext& eval_context,
                                            SemIR::InstId /*inst_id*/,
                                            SemIR::Inst inst)
    -> SemIR::ConstantId {
  auto branch = inst.As<SemIR::BranchWithArg>();
  eval_context.SetCurrentBlockArgValue(
      {.block_id = branch.target_id,
       .arg_id = eval_context.GetConstantValue(branch.arg_id)});
  eval_context.BranchTo(branch.target_id);
  return SemIR::ConstantId::None;
}

template <>
auto TryExecTypedInst<SemIR::Return>(FunctionExecContext& eval_context,
                                     SemIR::InstId /*inst_id*/,
                                     SemIR::Inst /*inst*/)
    -> SemIR::ConstantId {
  return MakeEmptyTupleResult(eval_context);
}

template <>
auto TryExecTypedInst<SemIR::ReturnExpr>(FunctionExecContext& eval_context,
                                         SemIR::InstId /*inst_id*/,
                                         SemIR::Inst inst)
    -> SemIR::ConstantId {