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

Code before:
        {.type_id = SemIR::TypeType::TypeId,
         .facet_value_inst_id = facet_or_type_id});
  }
  return context.types().GetTypeIdForTypeInstId(facet_or_type_id);
}

auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id,
                                 SemIR::LookupImplWitness eval_query,
                                 SemIR::InstId self_facet_value_inst_id,
                                 bool poison_final_results)
    -> EvalImplLookupResult {
  auto query_specific_interface =
      context.specific_interfaces().Get(eval_query.query_specific_interface_id);

  auto facet_lookup_result = LookupImplWitnessInSelfFacetValue(
      context, loc_id, self_facet_value_inst_id, query_specific_interface);
  if (facet_lookup_result.has_final_value()) {
    return facet_lookup_result;
  }

  // Check to see if this result is in the cache. But skip the cache in
  // `!poison_final_results` mode, as that indicates we're re-checking a
  // poisoned result and need to redo the lookup.
  std::pair impl_lookup_cache_key = {eval_query.query_self_inst_id,
                                     eval_query.query_specific_interface_id};
  if (poison_final_results) {
    if (auto result =
            context.impl_lookup_cache().Lookup(impl_lookup_cache_key)) {
      return EvalImplLookupResult::MakeFinal(result.value());
    }
  }

  // Ensure specifics don't substitute in weird things for the query self.
  CARBON_CHECK(context.types().IsFacetType(
      context.insts().Get(eval_query.query_self_inst_id).type_id()));
  SemIR::ConstantId query_self_const_id =
      context.constant_values().Get(eval_query.query_self_inst_id);

  // The kind of lookup we're performing, which determines what kind of result
  // we provide.
  enum LookupKind {
    // This is a concrete query, which should either provide a concrete witness
    // or fail.
    Concrete,
    // This query refers to an interface that can be found symbolically within
    // the facet type of the self value. The lookup will always succeed, but we
    // are still checking in case a more precise final impl supplies values of
    // associated constants.
    FoundInFacet,
    // This is an impl lookup with a symbolic query.
    Symbolic,

Review comment (performance):
How would you feel about
```
enum EvalImplLookupMode {
  PoisonFinalResults,
  AvoidCache,
}
```
Instead of the bool?

Specifically, the claim that not-poisoning means we're checking poison feels like a layering violation, and fragile. It would be nice to inscribe intent a little more.

Code after:
        {.type_id = SemIR::TypeType::TypeId,
         .facet_value_inst_id = facet_or_type_id});
  }
  return context.types().GetTypeIdForTypeInstId(facet_or_type_id);
}

auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id,
                                 SemIR::LookupImplWitness eval_query,
                                 SemIR::InstId self_facet_value_inst_id,
                                 EvalImplLookupMode mode)
    -> EvalImplLookupResult {
  auto query_specific_interface =
      context.specific_interfaces().Get(eval_query.query_specific_interface_id);

  auto facet_lookup_result = LookupImplWitnessInSelfFacetValue(
      context, loc_id, self_facet_value_inst_id, query_specific_interface);
  if (facet_lookup_result.has_final_value()) {
    return facet_lookup_result;
  }

  // Ensure specifics don't substitute in weird things for the query self.
  CARBON_CHECK(context.types().IsFacetType(
      context.insts().Get(eval_query.query_self_inst_id).type_id()));
  SemIR::ConstantId query_self_const_id =
      context.constant_values().Get(eval_query.query_self_inst_id);

  // Check to see if this result is in the cache. But skip the cache if
  // //we're re-checking a poisoned result and need to redo the lookup.
  std::pair impl_lookup_cache_key = {query_self_const_id,
                                     eval_query.query_specific_interface_id};
  if (mode != EvalImplLookupMode::RecheckPoisonedLookup) {
    if (auto result =
            context.impl_lookup_cache().Lookup(impl_lookup_cache_key)) {
      return EvalImplLookupResult::MakeFinal(result.value());
    }
  }

  // The kind of lookup we're performing, which determines what kind of result
  // we provide.
  enum LookupKind {
    // This is a concrete query, which should either provide a concrete witness
    // or fail.
    Concrete,
    // This query refers to an interface that can be found symbolically within
    // the facet type of the self value. The lookup will always succeed, but we
    // are still checking in case a more precise final impl supplies values of
    // associated constants.
    FoundInFacet,
    // This is an impl lookup with a symbolic query.
    Symbolic,
  };