// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #ifndef CARBON_TOOLCHAIN_CHECK_IMPL_LOOKUP_H_ #define CARBON_TOOLCHAIN_CHECK_IMPL_LOOKUP_H_ #include #include "toolchain/check/context.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { // Looks up the witnesses to use for a type value or facet value, and a facet // type naming a set of interfaces required to be implemented for that type, as // well as possible constraints on those interfaces. // // N.B. In the future, `TypeType` will become a facet type, at which point type // values will also be facet values. // // The return value is one of: // - An InstBlockId value, containing an `ImplWitness` instruction for each // required interface in the `query_facet_type_const_id`. This verifies the // facet type is satisfied for the type in `type_const_id`, and provides a // witness for accessing the impl of each interface. // // - `InstBlockId::None`, indicating lookup failed for at least one required // interface in the `query_facet_type_const_id`. The facet type is not // satisfied for the type in `type_const_id`. This represents lookup failure, // but is not an error, so no diagnostic is emitted. // // - An error value, indicating the program is invalid and a diagonstic has been // produced, either in this function or before. auto LookupImplWitness(Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, SemIR::ConstantId query_facet_type_const_id, bool diagnose = true) -> SemIR::InstBlockIdOrError; // Returns whether the query matches against the given impl. This is like a // `LookupImplWitness` operation but for a single interface, and against only // the single impl. auto LookupMatchesImpl(Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, SemIR::SpecificInterface query_specific_interface, SemIR::ImplId target_impl) -> bool; // Given a self facet, returns the canonical query self for a LookupImplWitness // instruction. The canonicalization looks through `FacetValue` and makes a // canonical form for `facet` and `facet as type`. // // If the input self facet is a `FacetValue` that is looked through, it can be // returned in `out_facet_value`, in order to preserve its facet type and // witnesses. auto GetCanonicalQuerySelfForLookupImplWitness( Context& context, SemIR::ConstantId self, SemIR::InstId* out_facet_value = nullptr) -> SemIR::ConstantId; // The kind of impl lookup being performed by a call to // `EvalLookupSingleFinalWitness`. enum class EvalImplLookupMode { // This is a regular impl lookup performed during check. If we produce a final // witness value that uses a specializable impl, the query will be poisoned so // that we will recheck it at the end of the compilation. Normal, // This is a re-check of a poisoned lookup being performed at the end of a // file. This disables any caching of lookup results for this query and redoes // the impl lookup. RecheckPoisonedLookup, }; // Looks for a final witness for an impl lookup query consisting of a self (type // or facet) and a single interface. This is for eval to execute lookup via the // `LookupImplWitness` instruction. Since this query is re-evaluated against // specifics, it provides monomorphization of the impl lookup, which allows for // finding specializations. auto EvalLookupSingleFinalWitness(Context& context, SemIR::LocId loc_id, SemIR::LookupImplWitness eval_query, SemIR::InstId self_facet_value_inst_id, EvalImplLookupMode mode) -> SemIR::ConstantId; } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_IMPL_LOOKUP_H_