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

Code before:
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorNotId node_id)
    -> bool {
  auto value_id = context.node_stack().PopExpr();
  value_id = ConvertToBoolValue(context, node_id, value_id);
  AddInstAndPush<SemIR::UnaryOperatorNot>(
      context, node_id,
      {.type_id = context.insts().Get(value_id).type_id(),
       .operand_id = value_id});
  return true;
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorPartialId node_id)
    -> bool {
  auto value_id = context.node_stack().PopExpr();
  auto inner_type = ExprAsType(context, node_id, value_id);
  auto class_type =
      context.types().TryGetAs<SemIR::ClassType>(inner_type.type_id);

  if (!class_type ||
      context.classes().Get(class_type->class_id).inheritance_kind ==
          SemIR::Class::InheritanceKind::Final) {
    CARBON_DIAGNOSTIC(PartialOnFinal, Error,
                      "`partial` applied to final type {0}", SemIR::TypeId);
    context.emitter().Emit(LocIdForDiagnostics::TokenOnly(node_id),
                           PartialOnFinal, inner_type.type_id);
  }

  // TODO: Add diagnostics for partial applied to non-base/abstract types.
  AddInstAndPush<SemIR::PartialType>(
      context, node_id,
      {.type_id = SemIR::TypeType::TypeId, .inner_id = inner_type.inst_id});
  return true;
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorPlusPlusId node_id)
    -> bool {
  return HandleUnaryOperator(context, node_id, {"Inc"});
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorStarId node_id)
    -> bool {
  auto base_id = context.node_stack().PopExpr();

  auto deref_base_id = PerformPointerDereference(
      context, node_id, base_id,
      [&context, &node_id](SemIR::TypeId not_pointer_type_id) {
        // TODO: Pass in the expression we're trying to dereference to produce a
        // better diagnostic.
        CARBON_DIAGNOSTIC(DerefOfNonPointer, Error,

Review comment (suggestion):
```suggestion
    context.emitter().Emit(node_id,
```

Drive-by -- is it fair to assume that `partial` doesn't have children, and so `TokenOnly` doesn't need to be done here? (I believe it's mainly for nodes with children, when we don't want to include the children)

Code after:
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorNotId node_id)
    -> bool {
  auto value_id = context.node_stack().PopExpr();
  value_id = ConvertToBoolValue(context, node_id, value_id);
  AddInstAndPush<SemIR::UnaryOperatorNot>(
      context, node_id,
      {.type_id = context.insts().Get(value_id).type_id(),
       .operand_id = value_id});
  return true;
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorPartialId node_id)
    -> bool {
  auto value_id = context.node_stack().PopExpr();
  auto inner_type = ExprAsType(context, node_id, value_id);
  auto class_type =
      context.types().TryGetAs<SemIR::ClassType>(inner_type.type_id);

  if (!class_type ||
      context.classes().Get(class_type->class_id).inheritance_kind ==
          SemIR::Class::InheritanceKind::Final) {
    CARBON_DIAGNOSTIC(PartialOnFinal, Error,
                      "`partial` applied to final type {0}", SemIR::TypeId);
    context.emitter().Emit(node_id, PartialOnFinal, inner_type.type_id);
  }

  // TODO: Add diagnostics for partial applied to non-base/abstract types.
  AddInstAndPush<SemIR::PartialType>(
      context, node_id,
      {.type_id = SemIR::TypeType::TypeId, .inner_id = inner_type.inst_id});
  return true;
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorPlusPlusId node_id)
    -> bool {
  return HandleUnaryOperator(context, node_id, {"Inc"});
}

auto HandleParseNode(Context& context, Parse::PrefixOperatorStarId node_id)
    -> bool {
  auto base_id = context.node_stack().PopExpr();

  auto deref_base_id = PerformPointerDereference(
      context, node_id, base_id,
      [&context, &node_id](SemIR::TypeId not_pointer_type_id) {
        // TODO: Pass in the expression we're trying to dereference to produce a
        // better diagnostic.
        CARBON_DIAGNOSTIC(DerefOfNonPointer, Error,
                          "cannot dereference operand of non-pointer type {0}",