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

Code before:
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    auto assoc_constant_decl =
        context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(decl_id);
    if (!assoc_constant_decl) {
      auto type_id = context.insts().Get(decl_id).type_id();
      auto type_inst = context.types().GetAsInst(type_id);
      auto fn_type = type_inst.As<SemIR::FunctionType>();
      const auto& fn = context.functions().Get(fn_type.function_id);
      CARBON_DIAGNOSTIC(RewriteForAssociatedFunction, Error,
                        "rewrite specified for associated function {0}",
                        SemIR::NameId);
      context.emitter().Emit(facet_type_inst_id, RewriteForAssociatedFunction,
                             fn.name_id);
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    if (table_entry != SemIR::ImplWitnessTablePlaceholder::SingletonInstId) {
      if (table_entry != rewrite_value) {
        CARBON_DIAGNOSTIC(
            AssociatedConstantWithDifferentValues, Error,
            "associated constant {0} given two different values {1} and {2}",
            SemIR::NameId, InstIdAsType, InstIdAsType);
        auto& assoc_const = context.associated_constants().Get(
            assoc_constant_decl->assoc_const_id);
        context.emitter().Emit(facet_type_inst_id,
                               AssociatedConstantWithDifferentValues,
                               assoc_const.name_id, table_entry, rewrite_value);
      }
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    // If the associated constant has a symbolic type, convert the rewrite
    // value to that type now we know the value of `Self`.
    SemIR::TypeId assoc_const_type_id = assoc_constant_decl->type_id;
    if (assoc_const_type_id.is_symbolic()) {
      // Get the type of the associated constant in this interface with this
      // value for `Self`.
      assoc_const_type_id = GetTypeForSpecificAssociatedEntity(
          context, facet_type_inst_id, interface_to_witness.specific_id,
          decl_id, context.types().GetTypeIdForTypeInstId(self_type_inst_id),
          witness_inst_id);
      // Perform the conversion of the value to the type. We skipped this when
      // forming the facet type because the type of the associated constant
      // was symbolic.
      auto converted_inst_id = ConvertToValueOfType(
          context, context.insts().GetLocId(facet_type_inst_id), rewrite_value,

Review comment (suggestion):
These `InstId`s need not be types. What happens if you have a test like
```
interface I { let N:! i32; }
impl () as I where .N = 1 and .N = 2 {}
```

Code after:
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    auto assoc_constant_decl =
        context.insts().TryGetAs<SemIR::AssociatedConstantDecl>(decl_id);
    if (!assoc_constant_decl) {
      auto type_id = context.insts().Get(decl_id).type_id();
      auto type_inst = context.types().GetAsInst(type_id);
      auto fn_type = type_inst.As<SemIR::FunctionType>();
      const auto& fn = context.functions().Get(fn_type.function_id);
      CARBON_DIAGNOSTIC(RewriteForAssociatedFunction, Error,
                        "rewrite specified for associated function {0}",
                        SemIR::NameId);
      context.emitter().Emit(facet_type_inst_id, RewriteForAssociatedFunction,
                             fn.name_id);
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    if (table_entry != SemIR::ImplWitnessTablePlaceholder::SingletonInstId) {
      if (table_entry != rewrite_value) {
        // TODO: Figure out how to print the two different values
        // `const_id` & `rewrite_value` in the diagnostic
        // message.
        CARBON_DIAGNOSTIC(AssociatedConstantWithDifferentValues, Error,
                          "associated constant {0} given two different values",
                          SemIR::NameId);
        auto& assoc_const = context.associated_constants().Get(
            assoc_constant_decl->assoc_const_id);
        context.emitter().Emit(facet_type_inst_id,
                               AssociatedConstantWithDifferentValues,
                               assoc_const.name_id);
      }
      table_entry = SemIR::ErrorInst::SingletonInstId;
      continue;
    }

    // If the associated constant has a symbolic type, convert the rewrite
    // value to that type now we know the value of `Self`.
    SemIR::TypeId assoc_const_type_id = assoc_constant_decl->type_id;
    if (assoc_const_type_id.is_symbolic()) {
      // Get the type of the associated constant in this interface with this
      // value for `Self`.
      assoc_const_type_id = GetTypeForSpecificAssociatedEntity(
          context, facet_type_inst_id, interface_to_witness.specific_id,
          decl_id, context.types().GetTypeIdForTypeInstId(self_type_inst_id),
          witness_inst_id);
      // Perform the conversion of the value to the type. We skipped this when
      // forming the facet type because the type of the associated constant
      // was symbolic.