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

Code before:
        }
        context.inst_block_stack().AddInstId(inst_id);
        return inst_id;
      }

      case SemIR::InstConstantNeedsInstIdKind::Permanent: {
        // Evaluation needs a permanent InstId. Add the instruction.
        break;
      }
    }
  }

  // TODO: For an implicit instruction, this reattempts evaluation.
  return AddInst(context, loc_id_and_inst);
}

auto EvalOrAddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
    -> SemIR::ConstantId {
  switch (loc_id_and_inst.inst.kind().constant_needs_inst_id()) {
    case SemIR::InstConstantNeedsInstIdKind::No: {
      // Evaluation doesn't need an InstId. Just do it.
      return TryEvalInstUnsafe(context, SemIR::InstId::None,
                               loc_id_and_inst.inst);
    }

    case SemIR::InstConstantNeedsInstIdKind::DuringEvaluation: {
      // Evaluation temporarily needs an InstId. Add one for now.
      auto inst_id = AddInstInNoBlock(context, loc_id_and_inst);
      return context.constant_values().Get(inst_id);
    }

    case SemIR::InstConstantNeedsInstIdKind::Permanent: {
      // Evaluation needs a permanent InstId. Add the instruction.
      auto inst_id = AddInst(context, loc_id_and_inst);
      return context.constant_values().Get(inst_id);
    }
  }
}

auto AddPlaceholderInstInNoBlock(Context& context,
                                 SemIR::LocIdAndInst loc_id_and_inst)
    -> SemIR::InstId {
  auto inst_id = context.sem_ir().insts().AddInNoBlock(loc_id_and_inst);
  CARBON_VLOG_TO(context.vlog_stream(), "AddPlaceholderInst: {0}\n",
                 loc_id_and_inst.inst);
  context.constant_values().Set(inst_id, SemIR::ConstantId::None);
  return inst_id;
}

auto AddPlaceholderInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
    -> SemIR::InstId {

Review comment (suggestion):
`CARBON_CHECK(!loc_id_and_inst.kind().has_cleanup())`? We need to add a has_cleanup() to the InstKind, though. It has other similar accessors.

Code after:
          // TODO: We didn't end up needing the `inst_id` instruction. Consider
          // removing it from `insts` if it's still the most recently added
          // instruction.
          CARBON_CHECK(result_inst_id != inst_id);
          return result_inst_id;
        }
        context.inst_block_stack().AddInstId(inst_id);
        return inst_id;
      }

      case SemIR::InstConstantNeedsInstIdKind::Permanent: {
        // Evaluation needs a permanent InstId. Add the instruction.
        break;
      }
    }
  }

  // TODO: For an implicit instruction, this reattempts evaluation.
  return AddInst(context, loc_id_and_inst);
}

auto EvalOrAddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
    -> SemIR::ConstantId {
  CARBON_CHECK(!loc_id_and_inst.inst.kind().has_cleanup());

  switch (loc_id_and_inst.inst.kind().constant_needs_inst_id()) {
    case SemIR::InstConstantNeedsInstIdKind::No: {
      // Evaluation doesn't need an InstId. Just do it.
      return TryEvalInstUnsafe(context, SemIR::InstId::None,
                               loc_id_and_inst.inst);
    }

    case SemIR::InstConstantNeedsInstIdKind::DuringEvaluation: {
      // Evaluation temporarily needs an InstId. Add one for now.
      auto inst_id = AddInstInNoBlock(context, loc_id_and_inst);
      // TODO: Consider removing `inst_id` from `insts` if it's still the most
      // recently added instruction.
      return context.constant_values().Get(inst_id);
    }

    case SemIR::InstConstantNeedsInstIdKind::Permanent: {
      // Evaluation needs a permanent InstId. Add the instruction.
      auto inst_id = AddInst(context, loc_id_and_inst);
      return context.constant_values().Get(inst_id);
    }
  }
}

auto AddPlaceholderInstInNoBlock(Context& context,
                                 SemIR::LocIdAndInst loc_id_and_inst)
    -> SemIR::InstId {