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

Code before:
  auto interface_specific_id =
      context.generics().GetSelfSpecific(interface_info.generic_id);

  // Register this declaration as declaring an associated entity.
  auto index = SemIR::ElementIndex(
      context.args_type_info_stack().PeekCurrentBlockContents().size());
  context.args_type_info_stack().AddInstId(decl_id);

  // Name lookup for the declaration's name should name the associated entity,
  // not the declaration itself.
  auto type_id =
      GetAssociatedEntityType(context, interface_id, interface_specific_id);
  return AddInst<SemIR::AssociatedEntity>(
      context, SemIR::LocId(decl_id),
      {.type_id = type_id, .index = index, .decl_id = decl_id});
}

// Returns the `Self` binding for an interface, given a specific for the
// interface and a generic for an associated entity within it.
static auto GetSelfBinding(Context& context,
                           SemIR::SpecificId interface_specific_id,
                           SemIR::GenericId assoc_entity_generic_id)
    -> SemIR::InstId {
  const auto& generic = context.generics().Get(assoc_entity_generic_id);
  if (!generic.bindings_id.has_value()) {
    // There will be no bindings if an error occurred.
    return SemIR::ErrorInst::InstId;
  }

  auto bindings = context.inst_blocks().Get(generic.bindings_id);
  auto interface_args_id =
      context.specifics().GetArgsOrEmpty(interface_specific_id);
  auto interface_args = context.inst_blocks().Get(interface_args_id);

  // The `Self` binding is the first binding after the interface's arguments.
  auto self_binding_id = bindings[interface_args.size()];

  // Check that we found the self binding. The binding might be a
  // `BindSymbolicName` or an `ImportRef` naming one.
  auto self_binding_const_inst_id =
      context.constant_values().GetConstantInstId(self_binding_id);
  auto bind_name_inst = context.insts().GetAs<SemIR::BindSymbolicName>(
      self_binding_const_inst_id);
  CARBON_CHECK(
      context.entity_names().Get(bind_name_inst.entity_name_id).name_id ==
          SemIR::NameId::SelfType,
      "Expected a Self binding, found {0}", bind_name_inst);

  return self_binding_id;
}


Review comment (suggestion):
is `assoc_entity_generic_id` an error? It would be preferable to check that. The point being we want to _propagate_ ErrorInst but not create it without emitting a diagnostic. This here is going from None to ErrorInst which looks odd.

Code after:
  auto interface_specific_id =
      context.generics().GetSelfSpecific(interface_info.generic_id);

  // Register this declaration as declaring an associated entity.
  auto index = SemIR::ElementIndex(
      context.args_type_info_stack().PeekCurrentBlockContents().size());
  context.args_type_info_stack().AddInstId(decl_id);

  // Name lookup for the declaration's name should name the associated entity,
  // not the declaration itself.
  auto type_id =
      GetAssociatedEntityType(context, interface_id, interface_specific_id);
  return AddInst<SemIR::AssociatedEntity>(
      context, SemIR::LocId(decl_id),
      {.type_id = type_id, .index = index, .decl_id = decl_id});
}

// Returns the `Self` binding for an interface, given a specific for the
// interface and a generic for an associated entity within it.
static auto GetSelfBinding(Context& context,
                           SemIR::SpecificId interface_specific_id,
                           SemIR::GenericId assoc_entity_generic_id)
    -> SemIR::InstId {
  const auto& generic = context.generics().Get(assoc_entity_generic_id);
  auto bindings = context.inst_blocks().Get(generic.bindings_id);
  auto interface_args_id =
      context.specifics().GetArgsOrEmpty(interface_specific_id);
  auto interface_args = context.inst_blocks().Get(interface_args_id);

  // The `Self` binding is the first binding after the interface's arguments.
  auto self_binding_id = bindings[interface_args.size()];

  // Check that we found the self binding. The binding might be a
  // `BindSymbolicName` or an `ImportRef` naming one.
  auto self_binding_const_inst_id =
      context.constant_values().GetConstantInstId(self_binding_id);
  auto bind_name_inst = context.insts().GetAs<SemIR::BindSymbolicName>(
      self_binding_const_inst_id);
  CARBON_CHECK(
      context.entity_names().Get(bind_name_inst.entity_name_id).name_id ==
          SemIR::NameId::SelfType,
      "Expected a Self binding, found {0}", bind_name_inst);

  return self_binding_id;
}

// Given a `Self` type and a witness that it implements an interface, along with
// that interface's `Self` binding, forms and returns a facet that can be used
// as the argument for that `Self` binding.
static auto GetSelfFacet(Context& context,
                         SemIR::SpecificId interface_specific_id,