diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index badcc1b0c681..af083888bf30 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -66,6 +66,7 @@ cc_library( "pattern.cpp", "pattern_match.cpp", "pointer_dereference.cpp", + "require_impls_stack.cpp", "return.cpp", "scope_stack.cpp", "subst.cpp", @@ -134,6 +135,7 @@ cc_library( "pending_block.h", "pointer_dereference.h", "region_stack.h", + "require_impls_stack.h", "return.h", "scope_index.h", "scope_stack.h", diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index be9027053bec..a6cedfa8672c 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -530,20 +530,21 @@ auto CheckUnit::CheckPoisonedConcreteImplLookupQueries() -> void { auto poisoned_queries = std::exchange(context_.poisoned_concrete_impl_lookup_queries(), {}); for (const auto& poison : poisoned_queries) { - auto witness_result = EvalLookupSingleImplWitness( - context_, poison.loc_id, poison.query, poison.query.query_self_inst_id, + auto found_witness_id = EvalLookupSingleFinalWitness( + context_, poison.loc_id, poison.query, SemIR::InstId::None, EvalImplLookupMode::RecheckPoisonedLookup); - CARBON_CHECK(witness_result.has_final_value()); - auto found_witness_id = witness_result.final_witness(); - if (found_witness_id == SemIR::ErrorInst::InstId) { + CARBON_CHECK(found_witness_id.has_value()); + if (found_witness_id == SemIR::ErrorInst::ConstantId) { // Errors may have been diagnosed with the impl used in the poisoned query // in the meantime (such as a missing definition). continue; } - if (found_witness_id != poison.impl_witness) { - auto witness_to_impl_id = [&](SemIR::InstId witness_id) { + if (found_witness_id != poison.witness_id) { + auto witness_to_impl_id = [&](SemIR::ConstantId witness_id) { + // TODO: Add and use constant_values().GetAs(). + auto inst_id = context_.constant_values().GetInstId(witness_id); auto table_id = context_.insts() - .GetAs(witness_id) + .GetAs(inst_id) .witness_table_id; return context_.insts() .GetAs(table_id) @@ -555,7 +556,7 @@ auto CheckUnit::CheckPoisonedConcreteImplLookupQueries() -> void { auto bad_impl_id = witness_to_impl_id(found_witness_id); const auto& bad_impl = context_.impls().Get(bad_impl_id); - auto prev_impl_id = witness_to_impl_id(poison.impl_witness); + auto prev_impl_id = witness_to_impl_id(poison.witness_id); const auto& prev_impl = context_.impls().Get(prev_impl_id); CARBON_DIAGNOSTIC( diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 24d6beb63271..b84c01bc170e 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -25,6 +25,7 @@ #include "toolchain/check/node_stack.h" #include "toolchain/check/param_and_arg_refs_stack.h" #include "toolchain/check/region_stack.h" +#include "toolchain/check/require_impls_stack.h" #include "toolchain/check/scope_stack.h" #include "toolchain/diagnostics/emitter.h" #include "toolchain/parse/node_ids.h" @@ -125,7 +126,7 @@ class Context { return field_decls_stack_; } - auto require_impls_stack() -> ArrayStack& { + auto require_impls_stack() -> RequireImplsStack& { return require_impls_stack_; } @@ -221,6 +222,9 @@ class Context { SemIR::ConstantId query_facet_type_const_id; // The location of the impl being looked at for the stack entry. SemIR::InstId impl_loc = SemIR::InstId::None; + // TODO: If we make a proper stack class, we only need one `diagnosed_cycle` + // field, which resets to false when the stack becomes empty. + bool diagnosed_cycle = false; }; auto impl_lookup_stack() -> llvm::SmallVector& { return impl_lookup_stack_; @@ -229,7 +233,7 @@ class Context { // A map from a (self, interface) pair to a final witness. using ImplLookupCacheKey = std::pair; - using ImplLookupCacheMap = Map; + using ImplLookupCacheMap = Map; auto impl_lookup_cache() -> ImplLookupCacheMap& { return impl_lookup_cache_; } // An impl lookup query that resulted in a concrete witness from finding an @@ -240,8 +244,8 @@ class Context { SemIR::LocId loc_id; // The query for a witness of an impl for an interface. SemIR::LookupImplWitness query; - // The resulting ImplWitness. - SemIR::InstId impl_witness; + // The resulting final witness. + SemIR::ConstantId witness_id; }; auto poisoned_concrete_impl_lookup_queries() -> llvm::SmallVector& { @@ -425,7 +429,7 @@ class Context { // The stack of RequireImpls for in-progress Interface and Constraint // definitions. - ArrayStack require_impls_stack_; + RequireImplsStack require_impls_stack_; // The stack used for qualified declaration name construction. DeclNameStack decl_name_stack_; diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index fcc8c5ae7169..bdefaf314e60 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1512,7 +1512,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id, // by finding impl witnesses for the target FacetType. auto lookup_result = LookupImplWitness( context, loc_id, sem_ir.constant_values().Get(type_inst_id), - sem_ir.types().GetConstantId(target.type_id)); + sem_ir.types().GetConstantId(target.type_id), target.diagnose); if (lookup_result.has_value()) { if (lookup_result.has_error_value()) { return SemIR::ErrorInst::InstId; diff --git a/toolchain/check/custom_witness.cpp b/toolchain/check/custom_witness.cpp index 63b7a2545f5c..21b3613eab53 100644 --- a/toolchain/check/custom_witness.cpp +++ b/toolchain/check/custom_witness.cpp @@ -377,7 +377,7 @@ static auto TypeCanDestroy(Context& context, static auto MakeDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) + SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness) -> std::optional { auto query_specific_interface = context.specific_interfaces().Get(query_specific_interface_id); @@ -387,6 +387,10 @@ static auto MakeDestroyWitness( return std::nullopt; } + if (!build_witness) { + return SemIR::InstId::None; + } + if (query_self_const_id.is_symbolic()) { return SemIR::InstId::None; } @@ -407,7 +411,7 @@ static auto MakeDestroyWitness( static auto MakeIntFitsInWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) + SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness) -> std::optional { auto query_specific_interface = context.specific_interfaces().Get(query_specific_interface_id); @@ -470,6 +474,10 @@ static auto MakeIntFitsInWitness( return std::nullopt; } + if (!build_witness) { + return SemIR::InstId::None; + } + return BuildCustomWitness(context, loc_id, query_self_const_id, query_specific_interface_id, {}); } @@ -477,15 +485,15 @@ static auto MakeIntFitsInWitness( auto LookupCustomWitness(Context& context, SemIR::LocId loc_id, CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) - -> std::optional { + SemIR::SpecificInterfaceId query_specific_interface_id, + bool build_witness) -> std::optional { switch (core_interface) { case CoreInterface::Destroy: return MakeDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface_id, build_witness); case CoreInterface::IntFitsIn: return MakeIntFitsInWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface_id, build_witness); case CoreInterface::Copy: case CoreInterface::CppUnsafeDeref: case CoreInterface::Default: diff --git a/toolchain/check/custom_witness.h b/toolchain/check/custom_witness.h index d8248dff6596..c3c7b47fb669 100644 --- a/toolchain/check/custom_witness.h +++ b/toolchain/check/custom_witness.h @@ -39,11 +39,15 @@ auto GetCoreInterface(Context& context, SemIR::InterfaceId interface_id) // Returns a witness for a `CoreInterface` `CustomWitness`. A return value of // `None` indicates a non-final witness should be produced, while `std::nullopt` // indicates the query is final and no witness can be produced. +// +// If `build_witness` is false, this function always returns `None` as the +// witness, whether it would be final or not. It is used to indicate the +// presence of such a witness without adding instructions for it. auto LookupCustomWitness(Context& context, SemIR::LocId loc_id, CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) - -> std::optional; + SemIR::SpecificInterfaceId query_specific_interface_id, + bool build_witness) -> std::optional; } // namespace Carbon::Check diff --git a/toolchain/check/eval_inst.cpp b/toolchain/check/eval_inst.cpp index 5b58fcd6a46d..445b04878120 100644 --- a/toolchain/check/eval_inst.cpp +++ b/toolchain/check/eval_inst.cpp @@ -281,48 +281,35 @@ auto EvalConstantInst(Context& /*context*/, SemIR::FunctionDecl inst) auto EvalConstantInst(Context& context, SemIR::InstId inst_id, SemIR::LookupImplWitness inst) -> ConstantEvalResult { + // If the monomorphized query self is a FacetValue, we may get a witness from + // it under limited circumstances. If no final witness is found though, we + // don't need to preserve it for future evaluations, so we strip it from the + // LookupImplWitness instruction to reduce the number of distinct constant + // values. + auto self_facet_value_inst_id = SemIR::InstId::None; + if (auto facet_value = context.insts().TryGetAs( + inst.query_self_inst_id)) { + self_facet_value_inst_id = + std::exchange(inst.query_self_inst_id, facet_value->type_inst_id); + } + // The self value is canonicalized in order to produce a canonical // LookupImplWitness instruction, avoiding multiple constant values for // `` and `` as type, which always have the same // lookup result. - auto self_facet_value_inst_id = + inst.query_self_inst_id = GetCanonicalFacetOrTypeValue(context, inst.query_self_inst_id); - // When we look for a witness in the (facet) type of self, we may get a - // concrete witness from a `FacetValue` (which is `self_facet_value_inst_id`) - // in which case this instruction evaluates to that witness. - // - // If we only get a symbolic witness result though, then this instruction - // evaluates to a `LookupImplWitness`. Since there was no concrete result in - // the `FacetValue`, we don't need to preserve it. By looking through the - // `FacetValue` at the type value it wraps to generate a more canonical value - // for a symbolic `LookupImplWitness`. This makes us produce the same constant - // value for symbolic lookups in `FacetValue(T)` and `T`, since they will - // always have the same lookup result later, when `T` is replaced in a - // specific by something that can provide a concrete witness. - if (auto facet_value = context.insts().TryGetAs( - self_facet_value_inst_id)) { - inst.query_self_inst_id = - GetCanonicalFacetOrTypeValue(context, facet_value->type_inst_id); - } else { - inst.query_self_inst_id = self_facet_value_inst_id; + auto witness_id = EvalLookupSingleFinalWitness(context, SemIR::LocId(inst_id), + inst, self_facet_value_inst_id, + EvalImplLookupMode::Normal); + if (witness_id == SemIR::ErrorInst::ConstantId) { + return ConstantEvalResult::Error; } - - auto result = EvalLookupSingleImplWitness(context, SemIR::LocId(inst_id), - inst, self_facet_value_inst_id, - EvalImplLookupMode::Normal); - if (!result.has_value()) { - // We use NotConstant to communicate back to impl lookup that the lookup - // failed. This can not happen for a deferred symbolic lookup in a generic - // eval block, since we only add the deferred lookup instruction (being - // evaluated here) to the SemIR if the lookup succeeds. - return ConstantEvalResult::NotConstant; + if (witness_id.has_value()) { + return ConstantEvalResult::Existing(witness_id); } - if (result.has_final_value()) { - return ConstantEvalResult::Existing( - context.constant_values().Get(result.final_witness())); - } - + // Try again when the query is modified by a specific. return ConstantEvalResult::NewSamePhase(inst); } diff --git a/toolchain/check/generic.cpp b/toolchain/check/generic.cpp index 6b1d5f341429..aee00116d8fc 100644 --- a/toolchain/check/generic.cpp +++ b/toolchain/check/generic.cpp @@ -147,8 +147,21 @@ class RebuildGenericConstantInEvalBlockCallbacks : public SubstInstCallbacks { auto ReuseUnchanged(SemIR::InstId orig_inst_id) -> SemIR::InstId override { auto inst = context().insts().Get(orig_inst_id); + + auto const_id = context().constant_values().Get(orig_inst_id); + const auto& symbolic = + context().constant_values().GetSymbolicConstant(const_id); + // Template actions are inserted into the eval block directly, instead of + // adding a new instruction, in `AddTemplateActionToEvalBlock`. This means + // any instruction that is symbolic because it contains a template action as + // an operand would Rebuild that operand with the same instruction. Then the + // dependent instruction would be reused unchanged. + bool is_template = + symbolic.dependence == SemIR::ConstantDependence::Template; + CARBON_CHECK( - (inst.IsOneOf()), + is_template || (inst.IsOneOf()), "Instruction {0} has symbolic constant value but no symbolic operands", inst); diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index 5491a2c9ff3b..d44e5dd3a8d4 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -184,7 +184,7 @@ auto HandleParseNode(Context& context, context.inst_block_stack().PeekOrAdd(); context.inst_block_stack().Push(); - context.require_impls_stack().PushArray(); + context.require_impls_stack().Push(interface_id); // We use the arg stack to build the witness table type. context.args_type_info_stack().Push(); @@ -213,8 +213,8 @@ auto HandleParseNode(Context& context, Parse::InterfaceDefinitionId /*node_id*/) auto associated_entities_id = context.args_type_info_stack().Pop(); auto require_impls_block_id = context.require_impls_blocks().Add( - context.require_impls_stack().PeekArray()); - context.require_impls_stack().PopArray(); + context.require_impls_stack().PeekTop()); + context.require_impls_stack().Pop(); auto& interface_info = context.interfaces().Get(interface_id); if (!interface_info.associated_entities_id.has_value()) { diff --git a/toolchain/check/handle_named_constraint.cpp b/toolchain/check/handle_named_constraint.cpp index a1370b8b8a49..1aa0c419dff8 100644 --- a/toolchain/check/handle_named_constraint.cpp +++ b/toolchain/check/handle_named_constraint.cpp @@ -184,7 +184,7 @@ auto HandleParseNode(Context& context, constraint_info.body_block_with_self_id = context.inst_block_stack().PeekOrAdd(); - context.require_impls_stack().PushArray(); + context.require_impls_stack().Push(named_constraint_id); context.node_stack().Push(node_id, named_constraint_id); return true; @@ -199,8 +199,8 @@ auto HandleParseNode(Context& context, context.inst_block_stack().Pop(); auto require_impls_block_id = context.require_impls_blocks().Add( - context.require_impls_stack().PeekArray()); - context.require_impls_stack().PopArray(); + context.require_impls_stack().PeekTop()); + context.require_impls_stack().Pop(); auto& constraint_info = context.named_constraints().Get(named_constraint_id); if (!constraint_info.complete) { diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index d821ef5c0894..13ed395d5637 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -158,10 +158,9 @@ static auto FindAssociatedImportIRs( // Returns true if a cycle was found and diagnosed. static auto FindAndDiagnoseImplLookupCycle( - Context& context, - const llvm::SmallVector& stack, + Context& context, llvm::SmallVector& stack, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::ConstantId query_facet_type_const_id) -> bool { + SemIR::ConstantId query_facet_type_const_id, bool diagnose) -> bool { // Deduction of the interface parameters can do further impl lookups, and we // need to ensure we terminate. // @@ -177,22 +176,26 @@ static auto FindAndDiagnoseImplLookupCycle( for (auto [i, entry] : llvm::enumerate(stack)) { if (entry.query_self_const_id == query_self_const_id && entry.query_facet_type_const_id == query_facet_type_const_id) { - auto facet_type_type_id = - context.types().GetTypeIdForTypeConstantId(query_facet_type_const_id); - CARBON_DIAGNOSTIC(ImplLookupCycle, Error, - "cycle found in search for impl of {0} for type {1}", - SemIR::TypeId, SemIR::TypeId); - auto builder = context.emitter().Build( - loc_id, ImplLookupCycle, facet_type_type_id, - context.types().GetTypeIdForTypeConstantId(query_self_const_id)); - for (const auto& active_entry : llvm::drop_begin(stack, i)) { - if (active_entry.impl_loc.has_value()) { - CARBON_DIAGNOSTIC(ImplLookupCycleNote, Note, - "determining if this impl clause matches", ); - builder.Note(active_entry.impl_loc, ImplLookupCycleNote); + if (diagnose && !stack.back().diagnosed_cycle) { + auto facet_type_type_id = context.types().GetTypeIdForTypeConstantId( + query_facet_type_const_id); + CARBON_DIAGNOSTIC(ImplLookupCycle, Error, + "cycle found in search for impl of {0} for type {1}", + SemIR::TypeId, SemIR::TypeId); + auto builder = context.emitter().Build( + loc_id, ImplLookupCycle, facet_type_type_id, + context.types().GetTypeIdForTypeConstantId(query_self_const_id)); + for (const auto& active_entry : llvm::drop_begin(stack, i)) { + if (active_entry.impl_loc.has_value()) { + CARBON_DIAGNOSTIC(ImplLookupCycleNote, Note, + "determining if this impl clause matches", ); + builder.Note(active_entry.impl_loc, ImplLookupCycleNote); + } } + builder.Emit(); } - builder.Emit(); + + stack.back().diagnosed_cycle = true; return true; } } @@ -209,7 +212,7 @@ struct RequiredImplsFromConstraint { static auto GetRequiredImplsFromConstraint( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::ConstantId query_facet_type_const_id) + SemIR::ConstantId query_facet_type_const_id, bool diagnose) -> std::optional { auto facet_type_inst_id = context.constant_values().GetInstId(query_facet_type_const_id); @@ -225,7 +228,8 @@ static auto GetRequiredImplsFromConstraint( "facet type {0} can not be identified", InstIdAsType); builder.Context(loc_id, ImplLookupInUnidentifiedFacetType, facet_type_inst_id); - }); + }, + diagnose); if (!identified_id.has_value()) { return std::nullopt; } @@ -235,12 +239,24 @@ static auto GetRequiredImplsFromConstraint( .other_requirements = facet_type_info.other_requirements}}; } -static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, - bool query_is_concrete, - SemIR::ConstantId query_self_const_id, - const SemIR::SpecificInterface& interface, - const SemIR::Impl& impl) - -> EvalImplLookupResult { +static auto TreatImplAsFinal(Context& context, const SemIR::Impl& impl) + -> bool { + // Lookups for the impl inside its own definition treat the impl as final. + // Nothing can specialize those lookups further, and it resolves any accesses + // of associated constants to their concrete values. + return IsImplEffectivelyFinal(context, impl) || impl.is_being_defined(); +} + +// Given a (possibly generic) `impl`, deduce a specific `impl` from the query +// self and specific for the interface. Return the witness ID of the `impl` of +// the resulting specific `impl`, if its specific interface matches the query. +// +// Note the witness also has the specific for the `impl` applied to it. +static auto TryGetSpecificWitnessIdForImpl( + Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id, + const SemIR::SpecificInterface& interface, const SemIR::Impl& impl) + -> SemIR::ConstantId { // The impl may have generic arguments, in which case we need to deduce them // to find what they are given the specific type and interface query. We use // that specific to map values in the impl to the deduced values. @@ -249,7 +265,7 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, specific_id = DeduceImplArguments( context, loc_id, impl, query_self_const_id, interface.specific_id); if (!specific_id.has_value()) { - return EvalImplLookupResult::MakeNone(); + return SemIR::ConstantId::None; } } @@ -265,7 +281,7 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, auto deduced_self_const_id = GetCanonicalFacetOrTypeValue(context, noncanonical_deduced_self_const_id); if (query_self_const_id != deduced_self_const_id) { - return EvalImplLookupResult::MakeNone(); + return SemIR::ConstantId::None; } // The impl's constraint is a facet type which it is implementing for the self @@ -276,7 +292,7 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific( context.sem_ir(), specific_id, impl.constraint_id)); if (deduced_constraint_id == SemIR::ErrorInst::InstId) { - return EvalImplLookupResult::MakeNone(); + return SemIR::ConstantId::None; } auto deduced_constraint_facet_type_id = @@ -289,7 +305,7 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, 1); if (deduced_constraint_facet_type_info.other_requirements) { - return EvalImplLookupResult::MakeNone(); + return SemIR::ConstantId::None; } // The specifics in the queried interface must match the deduced specifics in @@ -298,15 +314,19 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, deduced_constraint_facet_type_info.extend_constraints[0].specific_id; auto query_interface_specific_id = interface.specific_id; if (impl_interface_specific_id != query_interface_specific_id) { - return EvalImplLookupResult::MakeNone(); + return SemIR::ConstantId::None; } LoadImportRef(context, impl.witness_id); - if (specific_id.has_value()) { + if (!impl.is_being_defined() && specific_id.has_value()) { // If the impl definition can be resolved, eval will do it immediately; // otherwise, it can be resolved by further specialization. This is used to // resolve dependency chains when `MakeFinal` is returned without a concrete // definition; particularly final impls with symbolic constants. + // + // Note we do not do this for lookups _inside_ the definition of the impl, + // as that creates a cycle where resolving the definition must resolve the + // definition. AddInstInNoBlock( context, loc_id, SemIR::RequireSpecificDefinition{ @@ -315,77 +335,27 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, .specific_id = specific_id}); } - if (query_is_concrete || impl.is_final) { - // TODO: These final results should be cached somehow. Positive (non-None) - // results could be cached globally, as they can not change. But - // negative results can change after a final impl is written, so - // they can only be cached in a limited way, or the cache needs to - // be invalidated by writing a final impl that would match. - return EvalImplLookupResult::MakeFinal( - context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific( - context.sem_ir(), specific_id, impl.witness_id))); - } else { - return EvalImplLookupResult::MakeNonFinal(); - } + return SemIR::GetConstantValueInSpecific(context.sem_ir(), specific_id, + impl.witness_id); } -// Finds a lookup result from `query_self_inst_id` if it is a facet value that -// names the query interface in its facet type. Note that `query_self_inst_id` -// is allowed to be a non-canonical facet value in order to find a concrete -// witness, so it's not referenced as a constant value. -static auto LookupImplWitnessInSelfFacetValue( - Context& context, SemIR::LocId loc_id, - SemIR::InstId self_facet_value_inst_id, - SemIR::SpecificInterface query_specific_interface) -> EvalImplLookupResult { +// Identify the facet type of the query self. It is allowed to be partially +// identified. +static auto IdentifyQuerySelfFacetType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id) + -> SemIR::IdentifiedFacetTypeId { + auto query_self_inst_id = + context.constant_values().GetInstId(query_self_const_id); + auto facet_type = context.types().TryGetAs( - context.insts().Get(self_facet_value_inst_id).type_id()); + context.insts().Get(query_self_inst_id).type_id()); if (!facet_type) { - return EvalImplLookupResult::MakeNone(); + return SemIR::IdentifiedFacetTypeId::None; } - auto self_facet_value_const_id = - context.constant_values().Get(self_facet_value_inst_id); - - // The position of the interface in `required_impls()` is also the - // position of the witness for that interface in `FacetValue`. The - // `FacetValue` witnesses are the output of an impl lookup, which finds and - // returns witnesses in the same order. - auto identified_id = RequireIdentifiedFacetType( - context, loc_id, self_facet_value_const_id, *facet_type, - [&](auto& builder) { - CARBON_DIAGNOSTIC(ImplLookupInUnidentifiedFacetTypeOfQuerySelf, Context, - "facet type of value {0} can not be identified", - InstIdAsType); - builder.Context(loc_id, ImplLookupInUnidentifiedFacetTypeOfQuerySelf, - self_facet_value_inst_id); - }); - if (!identified_id.has_value()) { - return EvalImplLookupResult::MakeNone(); - } - auto facet_type_req_impls = llvm::enumerate( - context.identified_facet_types().Get(identified_id).required_impls()); - auto it = llvm::find_if(facet_type_req_impls, [&](auto e) { - auto [req_self, req_specific_interface] = e.value(); - // The `self_facet_value_inst_id` in eval is a canonicalized facet value, as - // is the self in the identified facet type. - return req_self == self_facet_value_const_id && - req_specific_interface == query_specific_interface; - }); - if (it == facet_type_req_impls.end()) { - return EvalImplLookupResult::MakeNone(); - } - auto index = (*it).index(); - - if (auto facet_value = context.insts().TryGetAs( - self_facet_value_inst_id)) { - auto witness_id = - context.inst_blocks().Get(facet_value->witnesses_block_id)[index]; - if (context.insts().IsOneOf( - witness_id)) { - return EvalImplLookupResult::MakeFinal(witness_id); - } - } - return EvalImplLookupResult::MakeNonFinal(); + return TryToIdentifyFacetType(context, loc_id, query_self_const_id, + *facet_type, + /*allow_partially_identified=*/true); } // Substitutes witnesess in place of `LookupImplWitness` queries into `.Self`, @@ -561,120 +531,6 @@ static auto VerifyQueryFacetTypeConstraints( return true; } -// Begin a search for an impl declaration matching the query. We do this by -// creating an LookupImplWitness instruction and evaluating. If it's able to -// find a final concrete impl, then it will evaluate to that `ImplWitness` but -// if not, it will evaluate to itself as a symbolic witness to be further -// evaluated with a more specific query when building a specific for the generic -// context the query came from. -static auto GetOrAddLookupImplWitness(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterface interface) - -> SemIR::InstId { - auto witness_const_id = EvalOrAddInst( - context, context.insts().GetLocIdForDesugaring(loc_id), - SemIR::LookupImplWitness{ - .type_id = GetSingletonType(context, SemIR::WitnessType::TypeInstId), - .query_self_inst_id = - context.constant_values().GetInstId(query_self_const_id), - .query_specific_interface_id = - context.specific_interfaces().Add(interface), - }); - // We use a NotConstant result from eval to communicate back an impl - // lookup failure. See `EvalConstantInst()` for `LookupImplWitness`. - if (!witness_const_id.is_constant()) { - return SemIR::InstId::None; - } - return context.constant_values().GetInstId(witness_const_id); -} - -auto LookupImplWitness(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId query_self_const_id, - SemIR::ConstantId query_facet_type_const_id) - -> SemIR::InstBlockIdOrError { - if (query_self_const_id == SemIR::ErrorInst::ConstantId || - query_facet_type_const_id == SemIR::ErrorInst::ConstantId) { - return SemIR::InstBlockIdOrError::MakeError(); - } - - { - // The query self value is a type value or a facet value. - auto query_self_type_id = - context.insts() - .Get(context.constant_values().GetInstId(query_self_const_id)) - .type_id(); - CARBON_CHECK((context.types().IsOneOf( - query_self_type_id))); - // The query facet type value is indeed a facet type. - CARBON_CHECK(context.insts().Is( - context.constant_values().GetInstId(query_facet_type_const_id))); - } - - auto req_impls_from_constraint = GetRequiredImplsFromConstraint( - context, loc_id, query_self_const_id, query_facet_type_const_id); - if (!req_impls_from_constraint) { - return SemIR::InstBlockIdOrError::MakeError(); - } - auto [req_impls, other_requirements] = *req_impls_from_constraint; - if (other_requirements) { - // TODO: Remove this when other requirements go away. - return SemIR::InstBlockId::None; - } - if (req_impls.empty()) { - return SemIR::InstBlockId::Empty; - } - - if (FindAndDiagnoseImplLookupCycle(context, context.impl_lookup_stack(), - loc_id, query_self_const_id, - query_facet_type_const_id)) { - return SemIR::InstBlockIdOrError::MakeError(); - } - - auto& stack = context.impl_lookup_stack(); - stack.push_back({ - .query_self_const_id = query_self_const_id, - .query_facet_type_const_id = query_facet_type_const_id, - }); - // We need to find a witness for each self+interface pair in `req_impls`. - // - // Every consumer of a facet type needs to agree on the order of interfaces - // used for its witnesses, which is done by following the order in the - // IdentifiedFacetType. - llvm::SmallVector result_witness_ids; - for (const auto& req_impl : req_impls) { - // TODO: Since both `interfaces` and `query_self_const_id` are sorted lists, - // do an O(N+M) merge instead of O(N*M) nested loops. - auto result_witness_id = - GetOrAddLookupImplWitness(context, loc_id, req_impl.self_facet_value, - req_impl.specific_interface); - if (result_witness_id.has_value()) { - result_witness_ids.push_back(result_witness_id); - } else { - // At least one queried interface in the facet type has no witness for the - // given type, we can stop looking for more. - break; - } - } - stack.pop_back(); - - // All interfaces in the query facet type must have been found to be available - // through some impl, or directly on the value's facet type if - // `query_self_const_id` is a facet value. - if (result_witness_ids.size() != req_impls.size()) { - return SemIR::InstBlockId::None; - } - - // Verify rewrite constraints in the query constraint are satisfied after - // applying the rewrites from the found witnesses. - if (!VerifyQueryFacetTypeConstraints(context, loc_id, query_self_const_id, - query_facet_type_const_id, req_impls, - result_witness_ids)) { - return SemIR::InstBlockId::None; - } - - return context.inst_blocks().AddCanonical(result_witness_ids); -} - // Returns whether the query is concrete, it is false if the self type or // interface specifics have a symbolic dependency. static auto QueryIsConcrete(Context& context, SemIR::ConstantId self_const_id, @@ -815,7 +671,7 @@ static auto CollectCandidateImplsForQuery( for (auto [id, impl] : context.impls().enumerate()) { CARBON_CHECK(impl.witness_id.has_value()); - if (final_only && !IsImplEffectivelyFinal(context, impl)) { + if (final_only && !TreatImplAsFinal(context, impl)) { continue; } @@ -870,36 +726,355 @@ static auto CollectCandidateImplsForQuery( return candidates; } +class IndexInFacetValue { + public: + static const IndexInFacetValue None; + static const IndexInFacetValue Unstable; + + explicit constexpr IndexInFacetValue(int32_t index) : index_(index) {} + + // Returns whether the value represents a successful attempt to find the index + // of an interface in a FacetValue. Returns true regardless of whether the + // index is stable and able to be used or not. + auto WasFound() const -> bool { return index_ != None.index_; } + + // Gets the stable index which can be used to index into the witness table in + // a FacetValue, if there is one. Otherwise, returns -1. + auto GetStableIndex() const -> int32_t { + if (index_ == Unstable.index_) { + return None.index_; + } + return index_; + } + + private: + int32_t index_; +}; + +inline constexpr auto IndexInFacetValue::None = IndexInFacetValue(-1); +inline constexpr auto IndexInFacetValue::Unstable = IndexInFacetValue(-2); + +// Looks in the facet type of the query self facet value and returns the index +// of `query_specific_interface` in the defined interface order for that facet +// type. The order comes from the `query_self_type_identified_id` which must be +// the IdentifiedFacetType of the type of `query_self_const_id `. +// +// If the query self is not a facet value, the IdentifiedFacetType would be +// None. +// +// The IdentifiedFacetType must not be partially identified in order to find an +// index, as that implies the interface order is not yet stable. In that case, +// no index will be found. +// +// If the `query_specific_interface` is not part of the facet type of the query +// self, returns -1 to indicate it was not found. +static auto IndexOfImplWitnessInSelfFacetValue( + Context& context, SemIR::ConstantId query_self_const_id, + SemIR::IdentifiedFacetTypeId query_self_type_identified_id, + SemIR::SpecificInterface query_specific_interface) -> IndexInFacetValue { + if (!query_self_type_identified_id.has_value()) { + return IndexInFacetValue::None; + } + + // The self in the identified facet type is a canonicalized facet value, so we + // canonicalize the query for comparison. + auto canonical_query_self_const_id = + GetCanonicalFacetOrTypeValue(context, query_self_const_id); + + const auto& identified = + context.identified_facet_types().Get(query_self_type_identified_id); + auto facet_type_req_impls = llvm::enumerate(identified.required_impls()); + auto it = llvm::find_if(facet_type_req_impls, [&](auto e) { + auto [req_self, req_specific_interface] = e.value(); + return req_self == canonical_query_self_const_id && + req_specific_interface == query_specific_interface; + }); + if (it == facet_type_req_impls.end()) { + return IndexInFacetValue::None; + } + + if (identified.partially_identified()) { + return IndexInFacetValue::Unstable; + } + return IndexInFacetValue(static_cast((*it).index())); +} + +static auto FindFinalWitnessFromSelfFacetValue( + Context& context, SemIR::ConstantId query_self_const_id, + SemIR::IdentifiedFacetTypeId query_self_type_identified_id, + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { + // TODO: Add and use constant_values().GetAs(). + auto query_self_inst_id = + context.constant_values().GetInstId(query_self_const_id); + auto facet_value = + context.insts().TryGetAs(query_self_inst_id); + if (!facet_value) { + return SemIR::InstId::None; + } + + auto index_in_facet_value = IndexOfImplWitnessInSelfFacetValue( + context, query_self_const_id, query_self_type_identified_id, + query_specific_interface); + auto stable_index = index_in_facet_value.GetStableIndex(); + if (stable_index < 0) { + return SemIR::InstId::None; + } + + auto witness_id = + context.inst_blocks().Get(facet_value->witnesses_block_id)[stable_index]; + if (context.insts().Is(witness_id)) { + // Did not find a final witness. + return SemIR::InstId::None; + } + + return witness_id; +} + +static auto FindNonFinalWitness( + Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id, + SemIR::IdentifiedFacetTypeId query_self_type_identified_id, + SemIR::SpecificInterface query_specific_interface) -> bool { + auto index = IndexOfImplWitnessInSelfFacetValue(context, query_self_const_id, + query_self_type_identified_id, + query_specific_interface); + if (index.WasFound()) { + return true; + } + + // TODO: Remove SpecificInterfaceId from LookupCustomWitness apis, switch to + // just SpecificInterface. + auto query_specific_interface_id = + context.specific_interfaces().Add(query_specific_interface); + + // Consider a custom witness for core interfaces. + // TODO: This needs to expand to more interfaces, and we might want to have + // that dispatch in custom_witness.cpp instead of here. + auto core_interface = + GetCoreInterface(context, query_specific_interface.interface_id); + if (auto witness_id = LookupCustomWitness( + context, loc_id, core_interface, query_self_const_id, + query_specific_interface_id, false)) { + // If there's a final witness, we would have already found it via evaluating + // the LookupImplWitness instruction. + CARBON_CHECK(!witness_id->has_value()); + return true; + } + + auto query_type_structure = BuildTypeStructure( + context, context.constant_values().GetInstId(query_self_const_id), + query_specific_interface); + // We looked for errors in the query self and facet type already, and we're + // not dealing with monomorphizations here. + CARBON_CHECK(query_type_structure, "error in impl lookup query"); + + auto candidates = CollectCandidateImplsForQuery( + context, /*final_only=*/false, query_self_const_id, *query_type_structure, + query_specific_interface); + + for (const auto& candidate : candidates.impls) { + const auto& impl = *candidate.impl; + context.impl_lookup_stack().back().impl_loc = impl.definition_id; + + auto witness_id = TryGetSpecificWitnessIdForImpl( + context, loc_id, query_self_const_id, query_specific_interface, impl); + if (witness_id.has_value()) { + // We looked for errors in the query self and facet type already, and + // we're not dealing with monomorphizations here. + CARBON_CHECK(witness_id != SemIR::ErrorInst::ConstantId, + "error in impl lookup query"); + return true; + } + } + + // C++ interop only provides final witnesses, so we don't look for a witness + // from C++ here. Those are found in eval of the `LookupImplWitness` + // instruction. + + return false; +} + +auto LookupImplWitness(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id, + SemIR::ConstantId query_facet_type_const_id, + bool diagnose) -> SemIR::InstBlockIdOrError { + if (query_self_const_id == SemIR::ErrorInst::ConstantId || + query_facet_type_const_id == SemIR::ErrorInst::ConstantId) { + return SemIR::InstBlockIdOrError::MakeError(); + } + + { + // The query self value is a type value or a facet value. + auto query_self_type_id = + context.insts() + .Get(context.constant_values().GetInstId(query_self_const_id)) + .type_id(); + CARBON_CHECK((context.types().IsOneOf( + query_self_type_id))); + // The query facet type value is indeed a facet type. + CARBON_CHECK(context.insts().Is( + context.constant_values().GetInstId(query_facet_type_const_id))); + } + + auto req_impls_from_constraint = + GetRequiredImplsFromConstraint(context, loc_id, query_self_const_id, + query_facet_type_const_id, diagnose); + if (!req_impls_from_constraint) { + return SemIR::InstBlockIdOrError::MakeError(); + } + auto [req_impls, other_requirements] = *req_impls_from_constraint; + if (other_requirements) { + // TODO: Remove this when other requirements go away. + return SemIR::InstBlockId::None; + } + if (req_impls.empty()) { + return SemIR::InstBlockId::Empty; + } + + // Cycles are diagnosed even if they are found when diagnostics are otherwise + // being suppressed (such as during deduce). + if (FindAndDiagnoseImplLookupCycle(context, context.impl_lookup_stack(), + loc_id, query_self_const_id, + query_facet_type_const_id, true)) { + return SemIR::InstBlockIdOrError::MakeError(); + } + + auto& stack = context.impl_lookup_stack(); + stack.push_back({ + .query_self_const_id = query_self_const_id, + .query_facet_type_const_id = query_facet_type_const_id, + .diagnosed_cycle = stack.empty() ? false : stack.back().diagnosed_cycle, + }); + // We need to find a witness for each self+interface pair in `req_impls`. + // + // Every consumer of a facet type needs to agree on the order of interfaces + // used for its witnesses, which is done by following the order in the + // IdentifiedFacetType of the query facet type, and this is represented in the + // order of the interfaces in `req_impls`. + llvm::SmallVector result_witness_ids; + for (const auto& req_impl : req_impls) { + // Identify the type of the requirement's self up front, if it's a facet, so + // we only have to do this once. + auto req_self_type_identified_id = + IdentifyQuerySelfFacetType(context, loc_id, req_impl.self_facet_value); + + // If the self facet contains a final witness for the required interface, we + // use that and avoid any further work. This is strictly an optimization, + // since that same final witness should be found by evaluating a + // LookupImplWitness instruction for the required self+interface pair. + auto result_witness_id = FindFinalWitnessFromSelfFacetValue( + context, req_impl.self_facet_value, req_self_type_identified_id, + req_impl.specific_interface); + if (result_witness_id.has_value()) { + // Found a final witness, use it. + result_witness_ids.push_back(result_witness_id); + continue; + } + + auto witness_const_id = EvalOrAddInst( + context, context.insts().GetLocIdForDesugaring(loc_id), + {.type_id = GetSingletonType(context, SemIR::WitnessType::TypeInstId), + .query_self_inst_id = + context.constant_values().GetInstId(req_impl.self_facet_value), + .query_specific_interface_id = + context.specific_interfaces().Add(req_impl.specific_interface)}); + result_witness_id = context.constant_values().GetInstId(witness_const_id); + if (!context.insts().Is(result_witness_id)) { + // Found a final witness, use it. + result_witness_ids.push_back(result_witness_id); + continue; + } + + if (QueryIsConcrete(context, req_impl.self_facet_value, + req_impl.specific_interface)) { + // Failed to find a final witness for a concrete query. There won't be a + // non-final witness, as any witness would have been treated as final. + break; + } + + // Did not find a final witness. If we find a non-final witness, then we use + // the `LookupImplWitness` as our witness so that monomorphization can + // produce a final witness later. + if (!FindNonFinalWitness(context, loc_id, req_impl.self_facet_value, + req_self_type_identified_id, + req_impl.specific_interface)) { + // At least one queried interface in the facet type has no witness for the + // given type, we can stop looking for more. + // + // TODO: The LookupImplWitness won't be used. We should find a way to + // discard it, which would remove it from the generic eval block if the + // lookup is within a generic context. + break; + } + + // Save the non-final witness, which will eventually resolve to a final + // witness as specifics are applied to make the query more concrete. + result_witness_ids.push_back(result_witness_id); + } + auto pop = stack.pop_back_val(); + if (pop.diagnosed_cycle && !stack.empty()) { + stack.back().diagnosed_cycle = true; + } + + // All interfaces in the query facet type must have been found to be available + // through some impl, or directly on the value's facet type if + // `query_self_const_id` is a facet value. + if (result_witness_ids.size() != req_impls.size()) { + return SemIR::InstBlockId::None; + } + + // Verify rewrite constraints in the query constraint are satisfied after + // applying the rewrites from the found witnesses. + if (!VerifyQueryFacetTypeConstraints(context, loc_id, query_self_const_id, + query_facet_type_const_id, req_impls, + result_witness_ids)) { + return SemIR::InstBlockId::None; + } + + return context.inst_blocks().AddCanonical(result_witness_ids); +} + // Record the query which found a final impl witness. It's illegal to // write a final impl afterward that would match the same query. static auto PoisonImplLookupQuery(Context& context, SemIR::LocId loc_id, EvalImplLookupMode mode, SemIR::LookupImplWitness eval_query, - const EvalImplLookupResult& result, + SemIR::ConstantId witness_id, const SemIR::Impl& impl) -> void { if (mode == EvalImplLookupMode::RecheckPoisonedLookup) { return; } - if (!result.has_final_value()) { - return; - } // If the impl was effectively final, then we don't need to poison here. A // change of query result will already be diagnosed at the point where the // new impl decl was written that changes the result. - if (IsImplEffectivelyFinal(context, impl)) { + if (TreatImplAsFinal(context, impl)) { return; } context.poisoned_concrete_impl_lookup_queries().push_back( - {.loc_id = loc_id, - .query = eval_query, - .impl_witness = result.final_witness()}); + {.loc_id = loc_id, .query = eval_query, .witness_id = witness_id}); } -auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, - SemIR::LookupImplWitness eval_query, - SemIR::InstId self_facet_value_inst_id, - EvalImplLookupMode mode) - -> EvalImplLookupResult { +// Return whether the `FacetType` in `type_id` extends a single interface, and +// that it matches `specific_interface`. +static auto FacetTypeIsSingleInterface( + Context& context, SemIR::TypeId type_id, + SemIR::SpecificInterface specific_interface) -> bool { + auto facet_type = context.types().GetAs(type_id); + const auto& facet_type_info = + context.facet_types().Get(facet_type.facet_type_id); + if (auto single = facet_type_info.TryAsSingleExtend()) { + if (auto* si = std::get_if(&*single)) { + return *si == specific_interface; + } + } + return false; +} + +auto EvalLookupSingleFinalWitness(Context& context, SemIR::LocId loc_id, + SemIR::LookupImplWitness eval_query, + SemIR::InstId self_facet_value_inst_id, + EvalImplLookupMode mode) + -> SemIR::ConstantId { auto query_specific_interface = context.specific_interfaces().Get(eval_query.query_specific_interface_id); @@ -909,40 +1084,59 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id = context.constant_values().Get(eval_query.query_self_inst_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; - } - - // If the self type is a facet that provides a witness, then we are in an - // `interface` or an `impl`. In both cases, we don't want to do any impl - // lookups. The query will eventually resolve to a concrete witness when it - // can get it from the self facet value, when it has a specific applied in the - // future. + // If the query self is monomorphized as a FacetValue, we can't use its + // witnesses in general, since we are not allowed to identify facet types in + // monomorphization. And we need to identify it to know which witness is for + // which interface. // - // In particular, this avoids a LookupImplWitness instruction in the eval - // block of an impl declaration from doing impl lookup. Specifically the - // lookup of the implicit .Self in `impl ... where .X`. If it does impl lookup - // when the eval block is run, it finds the same `impl`, tries to build a - // specific from it, which runs the eval block, creating a recursive loop that - // crashes. - if (facet_lookup_result.has_value()) { - if (auto bind = context.insts().TryGetAs( - eval_query.query_self_inst_id)) { - const auto& entity = context.entity_names().Get(bind->entity_name_id); - if (entity.name_id == SemIR::NameId::PeriodSelf || - entity.name_id == SemIR::NameId::SelfType) { - return facet_lookup_result; + // However, if the facet type has only a single interface and it matches the + // query, then we can use the witness, since there is only one. + // + // This looks like an optimization, but it's done to prefer the FacetValue's + // witness over the cached value for monomorphizations of `Self` inside an + // `impl` definition. If a final witness was previously found for the same + // type as the monomorphized `Self`, the cache would reuse it. But associated + // constants may differ in that witness from the current `impl`'s witness + // which leads to inconsistency within the impl definition. + // + // By preferring the impl's FacetValue, the `impl` remains self-consistent + // even if it's ultimately not valid due to a conflict. When a conflict with + // another `impl` does exist, a poisoning error will occur showing the two + // `impl`s are in disagreement for a concrete value, as the poisoning lookup + // does not preserve the FacetValue. + if (auto facet_value = context.insts().TryGetAsIfValid( + self_facet_value_inst_id)) { + if (FacetTypeIsSingleInterface(context, facet_value->type_id, + query_specific_interface)) { + auto witnesses = + context.inst_blocks().Get(facet_value->witnesses_block_id); + CARBON_CHECK(witnesses.size() == 1); + auto witness_inst_id = witnesses.front(); + // Only use the witness in monomoprhization if it's a final witness. + if (!context.insts().Is(witness_inst_id)) { + return context.constant_values().Get(witness_inst_id); } } } - auto query_type_structure = BuildTypeStructure( - context, context.constant_values().GetInstId(query_self_const_id), - query_specific_interface); - if (!query_type_structure) { - return EvalImplLookupResult::MakeNone(); + // If the query is on `.Self` and looking for the same interface as `.Self` + // provides, do not look for a witness in monomorphization - a non-final + // witness will be found from the facet type. This happens inside an `impl` + // declaration, and we must avoid finding that same `impl` and trying to + // deduce `.Self` for it, as that results in a specific declaration for the + // `impl` which evaluates this lookup again, producing a cycle. + // + // If the query is for `.Self` and for the facet type of `.Self`, then there + // is no final witness yet. + if (auto bind = context.insts().TryGetAs( + eval_query.query_self_inst_id)) { + const auto& entity = context.entity_names().Get(bind->entity_name_id); + if (entity.name_id == SemIR::NameId::PeriodSelf) { + if (FacetTypeIsSingleInterface(context, bind->type_id, + query_specific_interface)) { + return SemIR::ConstantId::None; + } + } } // Check to see if this result is in the cache. But skip the cache if we're @@ -952,37 +1146,37 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, if (mode != EvalImplLookupMode::RecheckPoisonedLookup) { if (auto result = context.impl_lookup_cache().Lookup(impl_lookup_cache_key)) { - return EvalImplLookupResult::MakeFinal(result.value()); + return result.value(); } } - // If the self value is a (symbolic) facet value that has a symbolic witness, - // then we don't need to do impl lookup, except that we want to find any final - // impls to return a concrete witness if possible. So we limit the query to - // final impls only in that case. Note as in the CHECK above, the query can - // not be concrete in this case, so only final impls can produce a concrete - // witness for this query. - auto candidates = CollectCandidateImplsForQuery( - context, facet_lookup_result.has_value(), query_self_const_id, - *query_type_structure, query_specific_interface); - bool query_is_concrete = QueryIsConcrete(context, query_self_const_id, query_specific_interface); - CARBON_CHECK(!query_is_concrete || !facet_lookup_result.has_value(), - "Non-concrete facet lookup value for concrete query"); - // Perform a lookup for an `impl` that matches the query. If we don't find a - // final impl, the self value may still have been a facet that provides a - // symbolic witness in the `facet_lookup_result`, which we want to fall back - // to. It records that an `impl` will exist for the query, but is yet unknown. + auto query_type_structure = BuildTypeStructure( + context, context.constant_values().GetInstId(query_self_const_id), + query_specific_interface); + if (!query_type_structure) { + // TODO: We should return an error here; an error was found in the type + // structure. + return SemIR::ConstantId::None; + } + + // We only want to return final witneses in monomorphization. If the query is + // concrete, we can find all impls, otherwise we want only (effectively) final + // impls. + auto candidates = CollectCandidateImplsForQuery( + context, /*final_only=*/!query_is_concrete, query_self_const_id, + *query_type_structure, query_specific_interface); struct LookupResult { - EvalImplLookupResult result; + SemIR::ConstantId witness_id = SemIR::ConstantId::None; + // Holds a pointer into `candidates`. const TypeStructure* impl_type_structure = nullptr; SemIR::LocId impl_loc_id = SemIR::LocId::None; }; - LookupResult lookup_result = {.result = facet_lookup_result}; + LookupResult lookup_result; auto core_interface = GetCoreInterface(context, query_specific_interface.interface_id); @@ -991,15 +1185,14 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, // TODO: This needs to expand to more interfaces, and we might want to have // that dispatch in custom_witness.cpp instead of here. bool used_custom_witness = false; - if (auto witness_id = LookupCustomWitness( + if (auto witness_inst_id = LookupCustomWitness( context, loc_id, core_interface, query_self_const_id, - eval_query.query_specific_interface_id)) { - if (witness_id->has_value()) { - lookup_result = {.result = EvalImplLookupResult::MakeFinal(*witness_id)}; - } else { - lookup_result = {.result = EvalImplLookupResult::MakeNonFinal()}; + eval_query.query_specific_interface_id, true)) { + if (witness_inst_id->has_value()) { + lookup_result = {.witness_id = + context.constant_values().Get(*witness_inst_id)}; + used_custom_witness = true; } - used_custom_witness = true; } // Only consider candidates when a custom witness didn't apply. @@ -1007,20 +1200,19 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, for (const auto& candidate : candidates.impls) { const auto& impl = *candidate.impl; - // In deferred lookup for a symbolic impl witness, while building a - // specific, there may be no stack yet as this may be the first lookup. If - // further lookups are started as a result in deduce, they will build the - // stack. + // In monomorphization, while resolving a specific, there may be no stack + // yet as this may be the first lookup. If further lookups are started as + // a result in deduce, they will build the stack. if (!context.impl_lookup_stack().empty()) { context.impl_lookup_stack().back().impl_loc = impl.definition_id; } - auto result = GetWitnessIdForImpl(context, loc_id, query_is_concrete, - query_self_const_id, - query_specific_interface, impl); - if (result.has_value()) { - PoisonImplLookupQuery(context, loc_id, mode, eval_query, result, impl); - lookup_result = {.result = result, + auto witness_id = TryGetSpecificWitnessIdForImpl( + context, loc_id, query_self_const_id, query_specific_interface, impl); + if (witness_id.has_value()) { + PoisonImplLookupQuery(context, loc_id, mode, eval_query, witness_id, + impl); + lookup_result = {.witness_id = witness_id, .impl_type_structure = &candidate.type_structure, .impl_loc_id = SemIR::LocId(impl.definition_id)}; break; @@ -1037,17 +1229,17 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, eval_query.query_specific_interface_id, lookup_result.impl_type_structure, lookup_result.impl_loc_id); if (cpp_witness_id.has_value()) { - lookup_result = {.result = - EvalImplLookupResult::MakeFinal(cpp_witness_id)}; + lookup_result = {.witness_id = + context.constant_values().Get(cpp_witness_id)}; } } if (mode != EvalImplLookupMode::RecheckPoisonedLookup && - lookup_result.result.has_final_value()) { + lookup_result.witness_id.has_value()) { context.impl_lookup_cache().Insert(impl_lookup_cache_key, - lookup_result.result.final_witness()); + lookup_result.witness_id); } - return lookup_result.result; + return lookup_result.witness_id; } auto LookupMatchesImpl(Context& context, SemIR::LocId loc_id, @@ -1057,10 +1249,14 @@ auto LookupMatchesImpl(Context& context, SemIR::LocId loc_id, if (query_self_const_id == SemIR::ErrorInst::ConstantId) { return false; } - auto result = GetWitnessIdForImpl( - context, loc_id, /*query_is_concrete=*/false, query_self_const_id, - query_specific_interface, context.impls().Get(target_impl)); - return result.has_value(); + auto witness_id = TryGetSpecificWitnessIdForImpl( + context, loc_id, query_self_const_id, query_specific_interface, + context.impls().Get(target_impl)); + // TODO: If this fails, it would be because there is an error in the specific + // interface. Should we check for that and return false? + CARBON_CHECK(witness_id != SemIR::ErrorInst::ConstantId, + "error in lookup specific interface"); + return witness_id.has_value(); } } // namespace Carbon::Check diff --git a/toolchain/check/impl_lookup.h b/toolchain/check/impl_lookup.h index 83ef2258143b..64f4491dafe8 100644 --- a/toolchain/check/impl_lookup.h +++ b/toolchain/check/impl_lookup.h @@ -36,8 +36,8 @@ namespace Carbon::Check { // 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) - -> SemIR::InstBlockIdOrError; + 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 @@ -47,57 +47,8 @@ auto LookupMatchesImpl(Context& context, SemIR::LocId loc_id, SemIR::SpecificInterface query_specific_interface, SemIR::ImplId target_impl) -> bool; -// The result of EvalLookupSingleImplWitness(). It can be one of: -// - No value. Lookup failed to find an impl declaration. -// - An effectively final value. Lookup found either a concrete impl or a -// `final` impl declaration; both can be used definitely. A witness is -// available. -// - A non-`final` symbolic value. Lookup found an impl, but it is not returned -// since lookup will need to be done again with a more specific query to look -// for specializations. -class [[nodiscard]] EvalImplLookupResult { - public: - static auto MakeNone() -> EvalImplLookupResult { - return EvalImplLookupResult(FoundNone()); - } - static auto MakeFinal(SemIR::InstId inst_id) -> EvalImplLookupResult { - return EvalImplLookupResult(inst_id); - } - static auto MakeNonFinal() -> EvalImplLookupResult { - return EvalImplLookupResult(FoundNonFinalImpl()); - } - - // True if an impl declaration was found, either effectively final or - // symbolic. - auto has_value() const -> bool { - return !std::holds_alternative(value_); - } - - // True if there is an effectively final witness in the result. If false, and - // `has_value()` is true, it means an impl was found that's not effectively - // final, and a further more specific query will need to be done. - auto has_final_value() const -> bool { - return std::holds_alternative(value_); - } - - // Returns the witness id for an effectively final value's impl declaration. - // Only valid to call if `has_final_value` is true. - auto final_witness() const -> SemIR::InstId { - return std::get(value_); - } - - private: - struct FoundNone {}; - struct FoundNonFinalImpl {}; - using Value = std::variant; - - explicit EvalImplLookupResult(Value value) : value_(value) {} - - Value value_; -}; - // The kind of impl lookup being performed by a call to -// `EvalLookupSingleImplWitness`. +// `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 @@ -109,16 +60,15 @@ enum class EvalImplLookupMode { RecheckPoisonedLookup, }; -// Looks for a witness instruction of an impl declaration for a query consisting -// of a type value or facet value, and a single interface. This is for eval to -// execute lookup via the LookupImplWitness instruction. It does not consider -// the self facet value for finding a witness, since LookupImplWitness() would -// have found that and not caused us to defer lookup to here. -auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id, - SemIR::LookupImplWitness eval_query, - SemIR::InstId self_facet_value_inst_id, - EvalImplLookupMode mode) - -> EvalImplLookupResult; +// 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 diff --git a/toolchain/check/require_impls_stack.cpp b/toolchain/check/require_impls_stack.cpp new file mode 100644 index 000000000000..0331af4eb513 --- /dev/null +++ b/toolchain/check/require_impls_stack.cpp @@ -0,0 +1,36 @@ +// 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 + +#include "toolchain/check/require_impls_stack.h" + +namespace Carbon::Check { + +auto RequireImplsStack::Push(EnclosingScopeId scope_id) -> void { + scope_ids_.push_back(scope_id); + array_stack_.PushArray(); +} + +auto RequireImplsStack::Pop() -> void { + scope_ids_.pop_back(); + array_stack_.PopArray(); +} + +auto RequireImplsStack::AppendToTop(SemIR::RequireImplsId id) -> void { + array_stack_.AppendToTop(id); +} + +auto RequireImplsStack::PeekTop() const + -> llvm::ArrayRef { + return array_stack_.PeekArray(); +} + +auto RequireImplsStack::PeekForScope(EnclosingScopeId scope_id) + -> llvm::ArrayRef { + auto it = std::find(scope_ids_.rbegin(), scope_ids_.rend(), scope_id); + CARBON_CHECK(it != scope_ids_.rend()); + auto index = std::distance(it, scope_ids_.rend()) - 1; + return array_stack_.PeekArrayAt(index); +} + +} // namespace Carbon::Check diff --git a/toolchain/check/require_impls_stack.h b/toolchain/check/require_impls_stack.h new file mode 100644 index 000000000000..e258bdd9d39a --- /dev/null +++ b/toolchain/check/require_impls_stack.h @@ -0,0 +1,44 @@ +// 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_REQUIRE_IMPLS_STACK_H_ +#define CARBON_TOOLCHAIN_CHECK_REQUIRE_IMPLS_STACK_H_ + +#include "common/array_stack.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::Check { + +// A stack where each frame holds an array of RequireImplsIds and is associated +// with an enclosing scope that can be searched for in the stack. +class RequireImplsStack { + public: + using EnclosingScopeId = + std::variant; + + // Push a new stack frame for an interface or named constraint to add + // RequireImplsIds. + auto Push(EnclosingScopeId scope_id) -> void; + // Pop the top stack frame and all its RequireImplsIds. + auto Pop() -> void; + + // Append to the top stack frame. + auto AppendToTop(SemIR::RequireImplsId id) -> void; + + // Returns the RequireImplsIds in the top stack frame. + auto PeekTop() const -> llvm::ArrayRef; + + // Finds the stack frame for a given scope and returns the RequireImplsIds in + // that stack frame. + auto PeekForScope(EnclosingScopeId scope_id) + -> llvm::ArrayRef; + + private: + llvm::SmallVector scope_ids_; + ArrayStack array_stack_; +}; + +} // namespace Carbon::Check + +#endif // CARBON_TOOLCHAIN_CHECK_REQUIRE_IMPLS_STACK_H_ diff --git a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon index c8e2ef54c394..8cef6931ec78 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon @@ -813,21 +813,21 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst7800016C: {kind: ImplWitness, arg0: inst78000124, arg1: specific78000021, type: type(inst(WitnessType))} // CHECK:STDOUT: inst7800016D: {kind: FunctionType, arg0: function78000005, arg1: specific78000021, type: type(TypeType)} // CHECK:STDOUT: inst7800016E: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant7800013C)} -// CHECK:STDOUT: inst7800016F: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} -// CHECK:STDOUT: inst78000170: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} -// CHECK:STDOUT: inst78000171: {kind: RequireSpecificDefinition, arg0: specific78000022, type: type(inst(RequireSpecificDefinitionType))} -// CHECK:STDOUT: inst78000172: {kind: LookupImplWitness, arg0: inst7800001D, arg1: specific_interface78000000, type: type(inst(WitnessType))} -// CHECK:STDOUT: inst78000173: {kind: LookupImplWitness, arg0: inst7800001E, arg1: specific_interface78000000, type: type(inst(WitnessType))} +// CHECK:STDOUT: inst7800016F: {kind: LookupImplWitness, arg0: inst7800001D, arg1: specific_interface78000000, type: type(inst(WitnessType))} +// CHECK:STDOUT: inst78000170: {kind: LookupImplWitness, arg0: inst7800001E, arg1: specific_interface78000000, type: type(inst(WitnessType))} +// CHECK:STDOUT: inst78000171: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} +// CHECK:STDOUT: inst78000172: {kind: RequireSpecificDefinition, arg0: specific7800000B, type: type(inst(RequireSpecificDefinitionType))} +// CHECK:STDOUT: inst78000173: {kind: RequireSpecificDefinition, arg0: specific78000022, type: type(inst(RequireSpecificDefinitionType))} // CHECK:STDOUT: inst78000174: {kind: FacetValue, arg0: inst7800001D, arg1: inst_block78000088, type: type(inst78000050)} // CHECK:STDOUT: inst78000175: {kind: FunctionType, arg0: function78000001, arg1: specific78000023, type: type(TypeType)} // CHECK:STDOUT: inst78000176: {kind: StructValue, arg0: inst_block_empty, type: type(symbolic_constant78000144)} // CHECK:STDOUT: inst78000177: {kind: FunctionTypeWithSelfType, arg0: inst78000175, arg1: inst78000174, type: type(TypeType)} -// CHECK:STDOUT: inst78000178: {kind: ImplWitnessAccess, arg0: inst78000172, arg1: element0, type: type(symbolic_constant7800014A)} -// CHECK:STDOUT: inst78000179: {kind: ImplWitnessAccess, arg0: inst78000172, arg1: element0, type: type(symbolic_constant78000146)} +// CHECK:STDOUT: inst78000178: {kind: ImplWitnessAccess, arg0: inst7800016F, arg1: element0, type: type(symbolic_constant7800014A)} +// CHECK:STDOUT: inst78000179: {kind: ImplWitnessAccess, arg0: inst7800016F, arg1: element0, type: type(symbolic_constant78000146)} // CHECK:STDOUT: inst7800017A: {kind: FacetValue, arg0: inst7800001E, arg1: inst_block7800008B, type: type(inst78000050)} // CHECK:STDOUT: inst7800017B: {kind: FunctionType, arg0: function78000001, arg1: specific78000024, type: type(TypeType)} // CHECK:STDOUT: inst7800017C: {kind: FunctionTypeWithSelfType, arg0: inst7800017B, arg1: inst7800017A, type: type(TypeType)} -// CHECK:STDOUT: inst7800017D: {kind: ImplWitnessAccess, arg0: inst78000173, arg1: element0, type: type(symbolic_constant7800014A)} +// CHECK:STDOUT: inst7800017D: {kind: ImplWitnessAccess, arg0: inst78000170, arg1: element0, type: type(symbolic_constant7800014A)} // CHECK:STDOUT: inst7800017E: {kind: BoundMethod, arg0: inst78000048, arg1: inst78000178, type: type(inst(BoundMethodType))} // CHECK:STDOUT: inst7800017F: {kind: SpecificImplFunction, arg0: inst78000178, arg1: specific78000025, type: type(inst(SpecificFunctionType))} // CHECK:STDOUT: inst78000180: {kind: SpecificImplFunction, arg0: inst78000179, arg1: specific78000025, type: type(inst(SpecificFunctionType))} @@ -930,7 +930,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst7800006B: concrete_constant(inst7800006B) // CHECK:STDOUT: inst7800006C: symbolic_constant78000017 // CHECK:STDOUT: inst7800006D: concrete_constant(inst7800006D) -// CHECK:STDOUT: inst7800006E: symbolic_constant78000142 +// CHECK:STDOUT: inst7800006E: symbolic_constant7800013F // CHECK:STDOUT: inst7800006F: constant // CHECK:STDOUT: inst78000070: concrete_constant(inst78000070) // CHECK:STDOUT: inst78000071: symbolic_constant7800002B @@ -1000,7 +1000,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst780000B1: concrete_constant(inst780000B1) // CHECK:STDOUT: inst780000B2: concrete_constant(inst(IntLiteralType)) // CHECK:STDOUT: inst780000B3: concrete_constant(inst78000050) -// CHECK:STDOUT: inst780000B4: symbolic_constant7800013E +// CHECK:STDOUT: inst780000B4: symbolic_constant78000140 // CHECK:STDOUT: inst780000B5: concrete_constant(inst780000B5) // CHECK:STDOUT: inst780000B6: constant // CHECK:STDOUT: inst780000B7: concrete_constant(inst780000B7) @@ -1187,9 +1187,9 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst7800016C: symbolic_constant7800013A // CHECK:STDOUT: inst7800016D: symbolic_constant7800013C // CHECK:STDOUT: inst7800016E: symbolic_constant7800013D -// CHECK:STDOUT: inst7800016F: symbolic_constant78000140 +// CHECK:STDOUT: inst7800016F: symbolic_constant7800013E // CHECK:STDOUT: inst78000170: symbolic_constant7800013F -// CHECK:STDOUT: inst78000171: symbolic_constant78000140 +// CHECK:STDOUT: inst78000171: symbolic_constant78000142 // CHECK:STDOUT: inst78000172: symbolic_constant78000141 // CHECK:STDOUT: inst78000173: symbolic_constant78000142 // CHECK:STDOUT: inst78000174: symbolic_constant78000143 @@ -1526,9 +1526,9 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: symbolic_constant7800013B: {inst: inst78000128, kind: checked, attached: {generic: generic78000009, index: generic_inst_in_def1}} // CHECK:STDOUT: symbolic_constant7800013C: {inst: inst78000127, kind: checked, attached: {generic: generic78000009, index: generic_inst_in_def0}} // CHECK:STDOUT: symbolic_constant7800013D: {inst: inst78000128, kind: checked, attached: {generic: generic78000009, index: generic_inst_in_def1}} -// CHECK:STDOUT: symbolic_constant7800013E: {inst: inst780000B8, kind: checked, attached: {generic: generic78000005, index: generic_inst_in_decl2}} -// CHECK:STDOUT: symbolic_constant7800013F: {inst: inst78000170, kind: checked, attached: null} -// CHECK:STDOUT: symbolic_constant78000140: {inst: inst78000170, kind: checked, attached: {generic: generic78000000, index: generic_inst_in_def2}} +// CHECK:STDOUT: symbolic_constant7800013E: {inst: inst7800016F, kind: checked, attached: null} +// CHECK:STDOUT: symbolic_constant7800013F: {inst: inst7800016F, kind: checked, attached: {generic: generic78000000, index: generic_inst_in_def2}} +// CHECK:STDOUT: symbolic_constant78000140: {inst: inst780000B8, kind: checked, attached: {generic: generic78000005, index: generic_inst_in_decl2}} // CHECK:STDOUT: symbolic_constant78000141: {inst: inst78000172, kind: checked, attached: null} // CHECK:STDOUT: symbolic_constant78000142: {inst: inst78000172, kind: checked, attached: {generic: generic78000000, index: generic_inst_in_def3}} // CHECK:STDOUT: symbolic_constant78000143: {inst: inst78000174, kind: checked, attached: null} @@ -2171,7 +2171,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst_block78000087: // CHECK:STDOUT: 0: inst78000019 // CHECK:STDOUT: inst_block78000088: -// CHECK:STDOUT: 0: inst78000172 +// CHECK:STDOUT: 0: inst7800016F // CHECK:STDOUT: inst_block78000089: // CHECK:STDOUT: 0: inst78000174 // CHECK:STDOUT: inst_block7800008A: @@ -2179,7 +2179,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: 1: inst78000175 // CHECK:STDOUT: 2: inst78000176 // CHECK:STDOUT: inst_block7800008B: -// CHECK:STDOUT: 0: inst78000173 +// CHECK:STDOUT: 0: inst78000170 // CHECK:STDOUT: inst_block7800008C: // CHECK:STDOUT: 0: inst7800017A // CHECK:STDOUT: inst_block7800008D: @@ -2197,7 +2197,7 @@ fn Foo[T:! type](p: T*) -> (T*, ()) { // CHECK:STDOUT: inst_block78000091: // CHECK:STDOUT: 0: inst78000043 // CHECK:STDOUT: 1: inst78000047 -// CHECK:STDOUT: 2: inst78000171 +// CHECK:STDOUT: 2: inst78000170 // CHECK:STDOUT: 3: inst78000173 // CHECK:STDOUT: 4: inst7800017A // CHECK:STDOUT: 5: inst7800017B diff --git a/toolchain/check/testdata/class/generic/basic.carbon b/toolchain/check/testdata/class/generic/basic.carbon index 4db598beffbe..c6fb9dff075e 100644 --- a/toolchain/check/testdata/class/generic/basic.carbon +++ b/toolchain/check/testdata/class/generic/basic.carbon @@ -63,8 +63,8 @@ class Declaration(T:! type); // CHECK:STDOUT: %specific_impl_fn.bdc: = specific_impl_function %impl.elem0.594, @Copy.WithSelf.Op(%T.035) [symbolic] // CHECK:STDOUT: %T.67d: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] -// CHECK:STDOUT: %.3a3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e7: = lookup_impl_witness %ptr.e7d, @Copy [symbolic] +// CHECK:STDOUT: %.3a3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e7d, (%Copy.lookup_impl_witness.2e7) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.486: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.b63: type = fn_type_with_self_type %Copy.WithSelf.Op.type.486, %Copy.facet [symbolic] @@ -195,8 +195,8 @@ class Declaration(T:! type); // CHECK:STDOUT: %require_complete.loc6_22: = require_complete_type %Class [symbolic = %require_complete.loc6_22 (constants.%require_complete.904)] // CHECK:STDOUT: %require_complete.loc6_36: = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_36 (constants.%require_complete.9dc)] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)] -// CHECK:STDOUT: %.loc7_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc7_12.1 (constants.%.3a3)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc6_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e7)] +// CHECK:STDOUT: %.loc7_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc7_12.1 (constants.%.3a3)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc6_36.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.486)] // CHECK:STDOUT: %.loc7_12.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc7_12.2 (constants.%.b63)] diff --git a/toolchain/check/testdata/class/generic/member_access.carbon b/toolchain/check/testdata/class/generic/member_access.carbon index d8d3e88804b6..6862d723bd67 100644 --- a/toolchain/check/testdata/class/generic/member_access.carbon +++ b/toolchain/check/testdata/class/generic/member_access.carbon @@ -91,8 +91,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %T.67d: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.2d4: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.74e: %ptr.as.Copy.impl.Op.type.2d4 = struct_value () [symbolic] -// CHECK:STDOUT: %.3a3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e7: = lookup_impl_witness %ptr.e7d, @Copy [symbolic] +// CHECK:STDOUT: %.3a3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic] // CHECK:STDOUT: %Copy.facet.8e7: %Copy.type = facet_value %ptr.e7d, (%Copy.lookup_impl_witness.2e7) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.486: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.8e7) [symbolic] // CHECK:STDOUT: %.b63: type = fn_type_with_self_type %Copy.WithSelf.Op.type.486, %Copy.facet.8e7 [symbolic] @@ -201,8 +201,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem.05d)] -// CHECK:STDOUT: %.loc15_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc15_12.1 (constants.%.3a3)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc13_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e7)] +// CHECK:STDOUT: %.loc15_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc15_12.1 (constants.%.3a3)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc13_36.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.8e7)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.486)] // CHECK:STDOUT: %.loc15_12.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc15_12.2 (constants.%.b63)] @@ -355,8 +355,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %require_complete.loc13_22 => constants.%complete_type.1ec // CHECK:STDOUT: %require_complete.loc13_36 => constants.%complete_type.3d0 // CHECK:STDOUT: %Class.elem => constants.%Class.elem.da5 -// CHECK:STDOUT: %.loc15_12.1 => constants.%.cab // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.843 +// CHECK:STDOUT: %.loc15_12.1 => constants.%.cab // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.a7b // CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.e01 // CHECK:STDOUT: %.loc15_12.2 => constants.%.a62 diff --git a/toolchain/check/testdata/class/generic/member_type.carbon b/toolchain/check/testdata/class/generic/member_type.carbon index 08b29160696c..ab60c118c802 100644 --- a/toolchain/check/testdata/class/generic/member_type.carbon +++ b/toolchain/check/testdata/class/generic/member_type.carbon @@ -446,8 +446,8 @@ fn Test() -> i32 { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4fd: = require_complete_type %C.131 [symbolic] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T [symbolic] -// CHECK:STDOUT: %.1f8: require_specific_def_type = require_specific_def @C.as.Inner.impl(%T) [symbolic] // CHECK:STDOUT: %Inner.lookup_impl_witness: = lookup_impl_witness %C.131, @Inner, @Inner(%T) [symbolic] +// CHECK:STDOUT: %.1f8: require_specific_def_type = require_specific_def @C.as.Inner.impl(%T) [symbolic] // CHECK:STDOUT: %Inner.facet.f78: %Inner.type.6ef = facet_value %C.131, (%Inner.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Inner.WithSelf.F.type.d96: type = fn_type @Inner.WithSelf.F, @Inner.WithSelf(%T, %Inner.facet.f78) [symbolic] // CHECK:STDOUT: %Inner.WithSelf.F.66d: %Inner.WithSelf.F.type.d96 = struct_value () [symbolic] @@ -731,8 +731,8 @@ fn Test() -> i32 { // CHECK:STDOUT: %require_complete.loc11_48: = require_complete_type %Inner.type [symbolic = %require_complete.loc11_48 (constants.%require_complete.8b6)] // CHECK:STDOUT: %Inner.assoc_type: type = assoc_entity_type @Inner, @Inner(%T) [symbolic = %Inner.assoc_type (constants.%Inner.assoc_type.be2)] // CHECK:STDOUT: %assoc0: @C.as.Inner.impl.F.%Inner.assoc_type (%Inner.assoc_type.be2) = assoc_entity element0, @Inner.WithSelf.%Inner.WithSelf.F.decl [symbolic = %assoc0 (constants.%assoc0.058)] -// CHECK:STDOUT: %.loc11_41.1: require_specific_def_type = require_specific_def @C.as.Inner.impl(%T) [symbolic = %.loc11_41.1 (constants.%.1f8)] // CHECK:STDOUT: %Inner.lookup_impl_witness: = lookup_impl_witness %C, @Inner, @Inner(%T) [symbolic = %Inner.lookup_impl_witness (constants.%Inner.lookup_impl_witness)] +// CHECK:STDOUT: %.loc11_41.1: require_specific_def_type = require_specific_def @C.as.Inner.impl(%T) [symbolic = %.loc11_41.1 (constants.%.1f8)] // CHECK:STDOUT: %Inner.facet: @C.as.Inner.impl.F.%Inner.type (%Inner.type.6ef) = facet_value %C, (%Inner.lookup_impl_witness) [symbolic = %Inner.facet (constants.%Inner.facet.f78)] // CHECK:STDOUT: %Inner.WithSelf.F.type: type = fn_type @Inner.WithSelf.F, @Inner.WithSelf(%T, %Inner.facet) [symbolic = %Inner.WithSelf.F.type (constants.%Inner.WithSelf.F.type.d96)] // CHECK:STDOUT: %.loc11_41.2: type = fn_type_with_self_type %Inner.WithSelf.F.type, %Inner.facet [symbolic = %.loc11_41.2 (constants.%.29b)] @@ -988,8 +988,8 @@ fn Test() -> i32 { // CHECK:STDOUT: %require_complete.loc11_48 => constants.%complete_type.087 // CHECK:STDOUT: %Inner.assoc_type => constants.%Inner.assoc_type.564 // CHECK:STDOUT: %assoc0 => constants.%assoc0.958 -// CHECK:STDOUT: %.loc11_41.1 => constants.%.c0b // CHECK:STDOUT: %Inner.lookup_impl_witness => constants.%Inner.impl_witness.d48 +// CHECK:STDOUT: %.loc11_41.1 => constants.%.c0b // CHECK:STDOUT: %Inner.facet => constants.%Inner.facet.ac9 // CHECK:STDOUT: %Inner.WithSelf.F.type => constants.%Inner.WithSelf.F.type.96b // CHECK:STDOUT: %.loc11_41.2 => constants.%.fd6 diff --git a/toolchain/check/testdata/deduce/binding_pattern.carbon b/toolchain/check/testdata/deduce/binding_pattern.carbon index 3834526e37e0..3f283458631c 100644 --- a/toolchain/check/testdata/deduce/binding_pattern.carbon +++ b/toolchain/check/testdata/deduce/binding_pattern.carbon @@ -99,6 +99,7 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %assoc0.3d8: %ImplicitAs.assoc_type.d88 = assoc_entity element0, imports.%Core.import_ref.201 [symbolic] // CHECK:STDOUT: %require_complete.cc6: = require_complete_type %ImplicitAs.type.1e5 [symbolic] // CHECK:STDOUT: %assoc0.843: %ImplicitAs.assoc_type.ff3 = assoc_entity element0, imports.%Core.import_ref.cc1 [symbolic] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %empty_struct_type, @ImplicitAs, @ImplicitAs(%V) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -200,6 +201,7 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %require_complete.loc19_16.2: = require_complete_type %ImplicitAs.type.loc19_16.2 [symbolic = %require_complete.loc19_16.2 (constants.%require_complete.cc6)] // CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.loc8_23.1) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.d88)] // CHECK:STDOUT: %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.d88) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.3d8)] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness constants.%empty_struct_type, @ImplicitAs, @ImplicitAs(%V.loc8_23.1) [symbolic = %ImplicitAs.lookup_impl_witness (constants.%ImplicitAs.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: @@ -300,6 +302,7 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %assoc0.a1c: %ImplicitAs.assoc_type.f30 = assoc_entity element0, imports.%Core.import_ref.201 [symbolic] // CHECK:STDOUT: %require_complete.24c: = require_complete_type %ImplicitAs.type.ee4 [symbolic] // CHECK:STDOUT: %assoc0.843: %ImplicitAs.assoc_type.ff3 = assoc_entity element0, imports.%Core.import_ref.cc1 [symbolic] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %empty_struct_type, @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -413,6 +416,7 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %require_complete.loc20_16.2: = require_complete_type %ImplicitAs.type.loc20_16.2 [symbolic = %require_complete.loc20_16.2 (constants.%require_complete.24c)] // CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.f30)] // CHECK:STDOUT: %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.f30) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.a1c)] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness constants.%empty_struct_type, @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic = %ImplicitAs.lookup_impl_witness (constants.%ImplicitAs.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: diff --git a/toolchain/check/testdata/eval/aggregates.carbon b/toolchain/check/testdata/eval/aggregates.carbon index d0da28cc1d5a..6d6e141f5671 100644 --- a/toolchain/check/testdata/eval/aggregates.carbon +++ b/toolchain/check/testdata/eval/aggregates.carbon @@ -493,8 +493,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %require_complete.666: = require_complete_type %tuple.type.3c8 [symbolic] // CHECK:STDOUT: %pattern_type.4ac: type = pattern_type %tuple.type.3c8 [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.type: type = facet_type <@DefaultOrUnformed> [concrete] -// CHECK:STDOUT: %.f7e: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%tuple.type.3c8) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.2ad: = lookup_impl_witness %tuple.type.3c8, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.f7e: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%tuple.type.3c8) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet.9a0: %DefaultOrUnformed.type = facet_value %tuple.type.3c8, (%DefaultOrUnformed.lookup_impl_witness.2ad) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.0af: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.9a0) [symbolic] // CHECK:STDOUT: %.246: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.0af, %DefaultOrUnformed.facet.9a0 [symbolic] @@ -503,8 +503,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %T.67d} [symbolic] // CHECK:STDOUT: %require_complete.5d6: = require_complete_type %struct_type.a [symbolic] // CHECK:STDOUT: %pattern_type.7b9: type = pattern_type %struct_type.a [symbolic] -// CHECK:STDOUT: %.d26: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%struct_type.a) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.169: = lookup_impl_witness %struct_type.a, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.d26: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%struct_type.a) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet.ca5: %DefaultOrUnformed.type = facet_value %struct_type.a, (%DefaultOrUnformed.lookup_impl_witness.169) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.0c5: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.ca5) [symbolic] // CHECK:STDOUT: %.9ac: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.0c5, %DefaultOrUnformed.facet.ca5 [symbolic] @@ -514,8 +514,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %array_type.742: type = array_type %int_5, %T.67d [symbolic] // CHECK:STDOUT: %require_complete.345: = require_complete_type %array_type.742 [symbolic] // CHECK:STDOUT: %pattern_type.d52: type = pattern_type %array_type.742 [symbolic] -// CHECK:STDOUT: %.617: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.742) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.945: = lookup_impl_witness %array_type.742, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.617: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.742) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet.ad6: %DefaultOrUnformed.type = facet_value %array_type.742, (%DefaultOrUnformed.lookup_impl_witness.945) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.2f0: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.ad6) [symbolic] // CHECK:STDOUT: %.544: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.2f0, %DefaultOrUnformed.facet.ad6 [symbolic] @@ -560,8 +560,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %array_type.2ec: type = array_type %Int.as.ImplicitAs.impl.Convert.call, %i32 [symbolic] // CHECK:STDOUT: %require_complete.5d1: = require_complete_type %array_type.2ec [symbolic] // CHECK:STDOUT: %pattern_type.99c: type = pattern_type %array_type.2ec [symbolic] -// CHECK:STDOUT: %.d6f: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.2ec) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.162: = lookup_impl_witness %array_type.2ec, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.d6f: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.2ec) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet.0c7: %DefaultOrUnformed.type = facet_value %array_type.2ec, (%DefaultOrUnformed.lookup_impl_witness.162) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.839: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.0c7) [symbolic] // CHECK:STDOUT: %.78e: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.839, %DefaultOrUnformed.facet.0c7 [symbolic] @@ -590,8 +590,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %tuple.type: type = tuple_type (%ptr.loc6_19.2, %const.loc6_22.2) [symbolic = %tuple.type (constants.%tuple.type.3c8)] // CHECK:STDOUT: %require_complete.loc6: = require_complete_type %tuple.type [symbolic = %require_complete.loc6 (constants.%require_complete.666)] // CHECK:STDOUT: %pattern_type.loc6: type = pattern_type %tuple.type [symbolic = %pattern_type.loc6 (constants.%pattern_type.4ac)] -// CHECK:STDOUT: %.loc6_30.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%tuple.type) [symbolic = %.loc6_30.3 (constants.%.f7e)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.loc6: = lookup_impl_witness %tuple.type, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness.loc6 (constants.%DefaultOrUnformed.lookup_impl_witness.2ad)] +// CHECK:STDOUT: %.loc6_30.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%tuple.type) [symbolic = %.loc6_30.3 (constants.%.f7e)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc6_30.2: %DefaultOrUnformed.type = facet_value %tuple.type, (%DefaultOrUnformed.lookup_impl_witness.loc6) [symbolic = %DefaultOrUnformed.facet.loc6_30.2 (constants.%DefaultOrUnformed.facet.9a0)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.loc6: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc6_30.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type.loc6 (constants.%DefaultOrUnformed.WithSelf.Op.type.0af)] // CHECK:STDOUT: %.loc6_30.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.loc6, %DefaultOrUnformed.facet.loc6_30.2 [symbolic = %.loc6_30.4 (constants.%.246)] @@ -600,8 +600,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %struct_type.a.loc7_23.2: type = struct_type {.a: @F.%T.loc4_6.1 (%T.67d)} [symbolic = %struct_type.a.loc7_23.2 (constants.%struct_type.a)] // CHECK:STDOUT: %require_complete.loc7: = require_complete_type %struct_type.a.loc7_23.2 [symbolic = %require_complete.loc7 (constants.%require_complete.5d6)] // CHECK:STDOUT: %pattern_type.loc7: type = pattern_type %struct_type.a.loc7_23.2 [symbolic = %pattern_type.loc7 (constants.%pattern_type.7b9)] -// CHECK:STDOUT: %.loc7_24.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%struct_type.a.loc7_23.2) [symbolic = %.loc7_24.3 (constants.%.d26)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.loc7: = lookup_impl_witness %struct_type.a.loc7_23.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness.loc7 (constants.%DefaultOrUnformed.lookup_impl_witness.169)] +// CHECK:STDOUT: %.loc7_24.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%struct_type.a.loc7_23.2) [symbolic = %.loc7_24.3 (constants.%.d26)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc7_24.2: %DefaultOrUnformed.type = facet_value %struct_type.a.loc7_23.2, (%DefaultOrUnformed.lookup_impl_witness.loc7) [symbolic = %DefaultOrUnformed.facet.loc7_24.2 (constants.%DefaultOrUnformed.facet.ca5)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.loc7: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc7_24.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type.loc7 (constants.%DefaultOrUnformed.WithSelf.Op.type.0c5)] // CHECK:STDOUT: %.loc7_24.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.loc7, %DefaultOrUnformed.facet.loc7_24.2 [symbolic = %.loc7_24.4 (constants.%.9ac)] @@ -610,8 +610,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %array_type.loc8_27.2: type = array_type constants.%int_5, %T.loc4_6.1 [symbolic = %array_type.loc8_27.2 (constants.%array_type.742)] // CHECK:STDOUT: %require_complete.loc8: = require_complete_type %array_type.loc8_27.2 [symbolic = %require_complete.loc8 (constants.%require_complete.345)] // CHECK:STDOUT: %pattern_type.loc8: type = pattern_type %array_type.loc8_27.2 [symbolic = %pattern_type.loc8 (constants.%pattern_type.d52)] -// CHECK:STDOUT: %.loc8_28.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.loc8_27.2) [symbolic = %.loc8_28.3 (constants.%.617)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness.loc8: = lookup_impl_witness %array_type.loc8_27.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness.loc8 (constants.%DefaultOrUnformed.lookup_impl_witness.945)] +// CHECK:STDOUT: %.loc8_28.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.loc8_27.2) [symbolic = %.loc8_28.3 (constants.%.617)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc8_28.2: %DefaultOrUnformed.type = facet_value %array_type.loc8_27.2, (%DefaultOrUnformed.lookup_impl_witness.loc8) [symbolic = %DefaultOrUnformed.facet.loc8_28.2 (constants.%DefaultOrUnformed.facet.ad6)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.loc8: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc8_28.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type.loc8 (constants.%DefaultOrUnformed.WithSelf.Op.type.2f0)] // CHECK:STDOUT: %.loc8_28.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.loc8, %DefaultOrUnformed.facet.loc8_28.2 [symbolic = %.loc8_28.4 (constants.%.544)] @@ -728,8 +728,8 @@ fn G(N:! i32) { // CHECK:STDOUT: %array_type.loc14_29.2: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc14_28.2, constants.%i32 [symbolic = %array_type.loc14_29.2 (constants.%array_type.2ec)] // CHECK:STDOUT: %require_complete: = require_complete_type %array_type.loc14_29.2 [symbolic = %require_complete (constants.%require_complete.5d1)] // CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc14_29.2 [symbolic = %pattern_type (constants.%pattern_type.99c)] -// CHECK:STDOUT: %.loc14_30.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.loc14_29.2) [symbolic = %.loc14_30.3 (constants.%.d6f)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %array_type.loc14_29.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness (constants.%DefaultOrUnformed.lookup_impl_witness.162)] +// CHECK:STDOUT: %.loc14_30.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%array_type.loc14_29.2) [symbolic = %.loc14_30.3 (constants.%.d6f)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc14_30.2: %DefaultOrUnformed.type = facet_value %array_type.loc14_29.2, (%DefaultOrUnformed.lookup_impl_witness) [symbolic = %DefaultOrUnformed.facet.loc14_30.2 (constants.%DefaultOrUnformed.facet.0c7)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc14_30.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type (constants.%DefaultOrUnformed.WithSelf.Op.type.839)] // CHECK:STDOUT: %.loc14_30.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type, %DefaultOrUnformed.facet.loc14_30.2 [symbolic = %.loc14_30.4 (constants.%.78e)] diff --git a/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon b/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon index 1131192e2c19..2040afd80a1e 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon @@ -558,11 +558,11 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %HandleTameAnimal2.type: type = fn_type @HandleTameAnimal2 [concrete] // CHECK:STDOUT: %HandleTameAnimal2: %HandleTameAnimal2.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.80f: = require_complete_type %W.binding.as_type [symbolic] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %W, @Eats [symbolic] // CHECK:STDOUT: %Animal.lookup_impl_witness: = lookup_impl_witness %W, @Animal [symbolic] // CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %W.binding.as_type, (%Animal.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Eats.impl_witness.8ab: = impl_witness @A.binding.as_type.as.Eats.impl.%Eats.impl_witness_table, @A.binding.as_type.as.Eats.impl(%Animal.facet) [symbolic] // CHECK:STDOUT: %.3cf: require_specific_def_type = require_specific_def @A.binding.as_type.as.Eats.impl(%Animal.facet) [symbolic] -// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %W, @Eats [symbolic] // CHECK:STDOUT: %Tame.lookup_impl_witness: = lookup_impl_witness %W, @Tame [symbolic] // CHECK:STDOUT: %facet_value: %facet_type.2db = facet_value %W.binding.as_type, (%Eats.lookup_impl_witness, %Tame.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %FeedTame2.specific_fn: = specific_function %FeedTame2, @FeedTame2(%facet_value) [symbolic] @@ -725,10 +725,10 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %W.binding.as_type [symbolic = %require_complete (constants.%require_complete.80f)] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %W.loc11_22.1, @Eats [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)] // CHECK:STDOUT: %Animal.lookup_impl_witness: = lookup_impl_witness %W.loc11_22.1, @Animal [symbolic = %Animal.lookup_impl_witness (constants.%Animal.lookup_impl_witness)] // CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %W.binding.as_type, (%Animal.lookup_impl_witness) [symbolic = %Animal.facet (constants.%Animal.facet)] // CHECK:STDOUT: %.loc12_14.2: require_specific_def_type = require_specific_def @A.binding.as_type.as.Eats.impl(%Animal.facet) [symbolic = %.loc12_14.2 (constants.%.3cf)] -// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %W.loc11_22.1, @Eats [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)] // CHECK:STDOUT: %Tame.lookup_impl_witness: = lookup_impl_witness %W.loc11_22.1, @Tame [symbolic = %Tame.lookup_impl_witness (constants.%Tame.lookup_impl_witness)] // CHECK:STDOUT: %facet_value.loc12_14.2: %facet_type.2db = facet_value %W.binding.as_type, (%Eats.lookup_impl_witness, %Tame.lookup_impl_witness) [symbolic = %facet_value.loc12_14.2 (constants.%facet_value)] // CHECK:STDOUT: %FeedTame2.specific_fn.loc12_3.2: = specific_function constants.%FeedTame2, @FeedTame2(%facet_value.loc12_14.2) [symbolic = %FeedTame2.specific_fn.loc12_3.2 (constants.%FeedTame2.specific_fn)] diff --git a/toolchain/check/testdata/facet/convert_facet_value_value_to_blanket_impl.carbon b/toolchain/check/testdata/facet/convert_facet_value_value_to_blanket_impl.carbon index 9cb350d4a792..489693c40103 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_value_to_blanket_impl.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_value_to_blanket_impl.carbon @@ -49,9 +49,9 @@ fn HandleAnimal[T:! Animal](a: T) { Feed(a); } // CHECK:STDOUT: %HandleAnimal.type: type = fn_type @HandleAnimal [concrete] // CHECK:STDOUT: %HandleAnimal: %HandleAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.72f: = require_complete_type %T.binding.as_type.e4f [symbolic] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %T.998, @Eats [symbolic] // CHECK:STDOUT: %Eats.impl_witness.760d13.2: = impl_witness @A.binding.as_type.as.Eats.impl.%Eats.impl_witness_table, @A.binding.as_type.as.Eats.impl(%T.998) [symbolic] // CHECK:STDOUT: %.860: require_specific_def_type = require_specific_def @A.binding.as_type.as.Eats.impl(%T.998) [symbolic] -// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %T.998, @Eats [symbolic] // CHECK:STDOUT: %Eats.facet.a05: %Eats.type = facet_value %T.binding.as_type.e4f, (%Eats.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Feed.specific_fn: = specific_function %Feed, @Feed(%Eats.facet.a05) [symbolic] // CHECK:STDOUT: } @@ -184,8 +184,8 @@ fn HandleAnimal[T:! Animal](a: T) { Feed(a); } // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.72f)] -// CHECK:STDOUT: %.loc22_43.2: require_specific_def_type = require_specific_def @A.binding.as_type.as.Eats.impl(%T.loc22_17.1) [symbolic = %.loc22_43.2 (constants.%.860)] // CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %T.loc22_17.1, @Eats [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)] +// CHECK:STDOUT: %.loc22_43.2: require_specific_def_type = require_specific_def @A.binding.as_type.as.Eats.impl(%T.loc22_17.1) [symbolic = %.loc22_43.2 (constants.%.860)] // CHECK:STDOUT: %Eats.facet.loc22_43.2: %Eats.type = facet_value %T.binding.as_type, (%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc22_43.2 (constants.%Eats.facet.a05)] // CHECK:STDOUT: %Feed.specific_fn.loc22_37.2: = specific_function constants.%Feed, @Feed(%Eats.facet.loc22_43.2) [symbolic = %Feed.specific_fn.loc22_37.2 (constants.%Feed.specific_fn)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon index f80a4b35b2fe..0e78f06e18c6 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon @@ -94,10 +94,10 @@ fn F() { // CHECK:STDOUT: %require_complete.72f: = require_complete_type %A.binding.as_type [symbolic] // CHECK:STDOUT: %require_complete.0a9: = require_complete_type %Food.binding.as_type.e7e [symbolic] // CHECK:STDOUT: %Eats.type.bb4cf6.2: type = facet_type <@Eats, @Eats(%Food.binding.as_type.e7e)> [symbolic] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %A, @Eats, @Eats(%Food.binding.as_type.e7e) [symbolic] // CHECK:STDOUT: %Eats.impl_witness.0150b7.2: = impl_witness @T.binding.as_type.as.Eats.impl.%Eats.impl_witness_table, @T.binding.as_type.as.Eats.impl(%A, %Food.2fc) [symbolic] // CHECK:STDOUT: %require_complete.a2722e.2: = require_complete_type %Eats.type.bb4cf6.2 [symbolic] // CHECK:STDOUT: %.f9e: require_specific_def_type = require_specific_def @T.binding.as_type.as.Eats.impl(%A, %Food.2fc) [symbolic] -// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %A, @Eats, @Eats(%Food.binding.as_type.e7e) [symbolic] // CHECK:STDOUT: %Eats.facet.702: %Eats.type.bb4cf6.2 = facet_value %A.binding.as_type, (%Eats.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %pattern_type.67b: type = pattern_type %Eats.type.bb4cf6.2 [symbolic] // CHECK:STDOUT: %Feed.specific_fn.1f9: = specific_function %Feed, @Feed(%Food.2fc, %Eats.facet.702) [symbolic] @@ -387,8 +387,8 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc32_45: = require_complete_type %A.binding.as_type [symbolic = %require_complete.loc32_45 (constants.%require_complete.72f)] // CHECK:STDOUT: %require_complete.loc32_54: = require_complete_type %Food.binding.as_type [symbolic = %require_complete.loc32_54 (constants.%require_complete.0a9)] -// CHECK:STDOUT: %.loc32_76.3: require_specific_def_type = require_specific_def @T.binding.as_type.as.Eats.impl(%A.loc32_17.1, %Food.loc32_29.1) [symbolic = %.loc32_76.3 (constants.%.f9e)] // CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %A.loc32_17.1, @Eats, @Eats(%Food.binding.as_type) [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)] +// CHECK:STDOUT: %.loc32_76.3: require_specific_def_type = require_specific_def @T.binding.as_type.as.Eats.impl(%A.loc32_17.1, %Food.loc32_29.1) [symbolic = %.loc32_76.3 (constants.%.f9e)] // CHECK:STDOUT: %Eats.type: type = facet_type <@Eats, @Eats(%Food.binding.as_type)> [symbolic = %Eats.type (constants.%Eats.type.bb4cf6.2)] // CHECK:STDOUT: %Eats.facet.loc32_76.2: @HandleAnimal.%Eats.type (%Eats.type.bb4cf6.2) = facet_value %A.binding.as_type, (%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc32_76.2 (constants.%Eats.facet.702)] // CHECK:STDOUT: %Feed.specific_fn.loc32_64.2: = specific_function constants.%Feed, @Feed(%Food.loc32_29.1, %Eats.facet.loc32_76.2) [symbolic = %Feed.specific_fn.loc32_64.2 (constants.%Feed.specific_fn.1f9)] @@ -562,13 +562,21 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc32_45 => constants.%complete_type.357 // CHECK:STDOUT: %require_complete.loc32_54 => constants.%complete_type.357 -// CHECK:STDOUT: %.loc32_76.3 => constants.%.767 // CHECK:STDOUT: %Eats.lookup_impl_witness => constants.%Eats.impl_witness.f54 +// CHECK:STDOUT: %.loc32_76.3 => constants.%.767 // CHECK:STDOUT: %Eats.type => constants.%Eats.type.8c2 // CHECK:STDOUT: %Eats.facet.loc32_76.2 => constants.%Eats.facet.a4e // CHECK:STDOUT: %Feed.specific_fn.loc32_64.2 => constants.%Feed.specific_fn.7dd // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Eats(constants.%Grass) { +// CHECK:STDOUT: %Food.loc21_16.1 => constants.%Grass +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Eats.type => constants.%Eats.type.8c2 +// CHECK:STDOUT: %Self.loc21_29.2 => constants.%Self.ebd +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T.binding.as_type.as.Eats.impl(constants.%Animal.facet, constants.%Edible.facet) { // CHECK:STDOUT: %T.loc26_14.2 => constants.%Animal.facet // CHECK:STDOUT: %U.loc26_26.2 => constants.%Edible.facet @@ -581,14 +589,6 @@ fn F() { // CHECK:STDOUT: %require_complete => constants.%complete_type.cf8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Eats(constants.%Grass) { -// CHECK:STDOUT: %Food.loc21_16.1 => constants.%Grass -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Eats.type => constants.%Eats.type.8c2 -// CHECK:STDOUT: %Self.loc21_29.2 => constants.%Self.ebd -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @Eats.WithSelf(constants.%Grass, constants.%Self.857) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/facet/fail_convert_facet_value_to_missing_impl.carbon b/toolchain/check/testdata/facet/fail_convert_facet_value_to_missing_impl.carbon index 4d627afc202d..2f8dbe012c73 100644 --- a/toolchain/check/testdata/facet/fail_convert_facet_value_to_missing_impl.carbon +++ b/toolchain/check/testdata/facet/fail_convert_facet_value_to_missing_impl.carbon @@ -49,6 +49,7 @@ fn HandleAnimal[T:! Animal](a: T) { Feed(a); } // CHECK:STDOUT: %HandleAnimal.type: type = fn_type @HandleAnimal [concrete] // CHECK:STDOUT: %HandleAnimal: %HandleAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.72f: = require_complete_type %T.binding.as_type.e4f [symbolic] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %T.998, @Eats [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -150,6 +151,7 @@ fn HandleAnimal[T:! Animal](a: T) { Feed(a); } // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.72f)] +// CHECK:STDOUT: %Eats.lookup_impl_witness: = lookup_impl_witness %T.loc27_17.1, @Eats [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%a.param: @HandleAnimal.%T.binding.as_type (%T.binding.as_type.e4f)) { // CHECK:STDOUT: !entry: diff --git a/toolchain/check/testdata/facet/fail_incomplete.carbon b/toolchain/check/testdata/facet/fail_incomplete.carbon deleted file mode 100644 index 5d1477f7ecf9..000000000000 --- a/toolchain/check/testdata/facet/fail_incomplete.carbon +++ /dev/null @@ -1,33 +0,0 @@ -// 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 -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/fail_incomplete.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/fail_incomplete.carbon - -// --- fail_impl_lookup_incomplete.carbon -library "[[@TEST_NAME]]"; - -constraint Z; - -fn AsZ(unused T:! Z) {} - -fn F() { - // Requires Z identified. - // CHECK:STDERR: fail_impl_lookup_incomplete.carbon:[[@LINE+10]]:3: error: facet type `Z` can not be identified [ImplLookupInUnidentifiedFacetType] - // CHECK:STDERR: AsZ(()); - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: fail_impl_lookup_incomplete.carbon:[[@LINE-9]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] - // CHECK:STDERR: constraint Z; - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: fail_impl_lookup_incomplete.carbon:[[@LINE-10]]:15: note: initializing generic parameter `T` declared here [InitializingGenericParam] - // CHECK:STDERR: fn AsZ(unused T:! Z) {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - AsZ(()); -} diff --git a/toolchain/check/testdata/facet/partially_identified.carbon b/toolchain/check/testdata/facet/partially_identified.carbon new file mode 100644 index 000000000000..e90956961983 --- /dev/null +++ b/toolchain/check/testdata/facet/partially_identified.carbon @@ -0,0 +1,216 @@ +// 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 +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/partially_identified.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/partially_identified.carbon + +// --- fail_self_doesnt_meet_constraint.carbon +library "[[@TEST_NAME]]"; + +interface Y {} +interface NeedsY(T:! Y) {} +constraint W { + // CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE+7]]:24: error: cannot convert type `Self` that implements `W` into type implementing `Y` [ConversionFailureFacetToFacet] + // CHECK:STDERR: extend require impls NeedsY(Self); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE-5]]:18: note: initializing generic parameter `T` declared here [InitializingGenericParam] + // CHECK:STDERR: interface NeedsY(T:! Y) {} + // CHECK:STDERR: ^ + // CHECK:STDERR: + extend require impls NeedsY(Self); +} + +// --- self_meets_constraint.carbon +library "[[@TEST_NAME]]"; + +interface Y {} +interface NeedsY(T:! Y) {} +constraint W { + require impls Y; + extend require impls NeedsY(Self); +} + +fn F(w:! W) { + w as Y; + w as NeedsY(w); +} + +// --- self_meets_constraint_through_indirection.carbon +library "[[@TEST_NAME]]"; + +interface Y {} +interface NeedsY(T:! Y) {} +constraint GivesY { + require impls Y; +} +constraint W { + require impls GivesY; + extend require impls NeedsY(Self); +} + +fn F(w:! W) { + w as Y; + w as NeedsY(w); +} + +// --- self_in_constraint_specific_interface.carbon +library "[[@TEST_NAME]]"; + +interface Y {} +interface NeedsY(T:! Y) {} + +// All types impl Y. This requires an impl lookup to find a witness, and it will +// be a symbolic witness for a symbolic self type. +impl forall [T:! type] T as Y {} + +constraint W { + // Constructs a FacetValue of `Self as Y`, containing the impl lookup + // instruction as its witness, which will be part of the generic definition of + // this require. + require impls NeedsY(Self); +} + +class C {} +impl C as NeedsY(C) {} + +fn G(w:! W) { + // The witness of NeedsY(Self) monomorphized by `w` must be the same as the + // witness of `NeedsY(w)` constructed directly here in order for this to find + // `NeedsY(w)` in the facet type `W`. + w as NeedsY(w); +} + +fn F() { + // Further monomorphize `NeedsY(w)` to `NeedsY(C)`. + G(C); +} + +// --- fail_todo_facet_access_type_of_self_meets_constraint.carbon +library "[[@TEST_NAME]]"; + +class C(T:! type) {} + +interface Y {} +interface NeedsY(T:! Y) {} +constraint W { + require C(Self) impls Y; + // CHECK:STDERR: fail_todo_facet_access_type_of_self_meets_constraint.carbon:[[@LINE+7]]:17: error: cannot convert type `C(Self)` into type implementing `Y` [ConversionFailureTypeToFacet] + // CHECK:STDERR: require impls NeedsY(C(Self)); + // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_facet_access_type_of_self_meets_constraint.carbon:[[@LINE-6]]:18: note: initializing generic parameter `T` declared here [InitializingGenericParam] + // CHECK:STDERR: interface NeedsY(T:! Y) {} + // CHECK:STDERR: ^ + // CHECK:STDERR: + require impls NeedsY(C(Self)); +} + +fn F(w:! W) { + // TODO: Lookups for `C(w) as ` need to look into the facet types + // of any facet value in the type `C(w)`, so that it can find a witness from + // the constraint `W`. + // CHECK:STDERR: fail_todo_facet_access_type_of_self_meets_constraint.carbon:[[@LINE+4]]:3: error: cannot convert type `C(w)` into type implementing `Y` [ConversionFailureTypeToFacet] + // CHECK:STDERR: C(w) as Y; + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + C(w) as Y; + // CHECK:STDERR: fail_todo_facet_access_type_of_self_meets_constraint.carbon:[[@LINE+7]]:11: error: cannot convert type `C(w)` into type implementing `Y` [ConversionFailureTypeToFacet] + // CHECK:STDERR: C(w) as NeedsY(C(w)); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_facet_access_type_of_self_meets_constraint.carbon:[[@LINE-25]]:18: note: initializing generic parameter `T` declared here [InitializingGenericParam] + // CHECK:STDERR: interface NeedsY(T:! Y) {} + // CHECK:STDERR: ^ + // CHECK:STDERR: + C(w) as NeedsY(C(w)); +} + +// --- multiple_use_of_self.carbon +library "[[@TEST_NAME]]"; + +interface Y {} +interface NeedsY(T:! Y) {} +interface NeedsNeedsY(T:! Y, U:! NeedsY(T)) {} +constraint W { + require impls Y; + // The identified facet type of Self is {Y}. + extend require impls NeedsY(Self); + // The identified facet type of Self is {Y, NeedsY}. Ensure we don't keep + // seeing the previous identified facet type of Self. + extend require impls NeedsNeedsY(Self, Self); +} + +fn F(w:! W) { + w as Y; + w as NeedsY(w); +} + +// --- access_through_previous_require.carbon +library "[[@TEST_NAME]]"; + +interface Z { let Z0:! type; } +interface Y {} +interface X { + let X0:! type; + fn XF() -> X0; +} + +class P(T:! type) { adapt (); } + +constraint M { + require impls Z where .Z0 = {}; + require impls Y; +} +constraint N { + require impls M; + // The facts from M travel back to here. + require impls X where .X0 = P(Self.(Z.Z0)); +} + +fn F(T:! N) -> T.(X.X0) { return T.(X.XF)(); } + +fn G() -> P({}) { + class C {} + impl C as Z where .Z0 = {} {} + impl C as Y {} + impl C as X where .X0 = P({}) { + fn XF() -> P({}) { return () as P({}); } + } + return F(C); +} + +// --- fail_impl_lookup_target_partially_identified.carbon +library "[[@TEST_NAME]]"; + +interface Z {} + +interface X { let XZ:! Z; } +constraint W { + require impls Z; + // Target of impl lookup can not be partially identified. + // CHECK:STDERR: fail_impl_lookup_target_partially_identified.carbon:[[@LINE+7]]:32: error: facet type `Z & W` can not be identified [ImplLookupInUnidentifiedFacetType] + // CHECK:STDERR: require impls X where .XZ = (Self as (W & Z)); + // CHECK:STDERR: ^~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_lookup_target_partially_identified.carbon:[[@LINE-6]]:1: note: constraint is currently being defined [NamedConstraintIncompleteWithinDefinition] + // CHECK:STDERR: constraint W { + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: + require impls X where .XZ = (Self as (W & Z)); +} + +// --- convert_from_forward_declaration.carbon +library "[[@TEST_NAME]]"; + +interface Z {} +// The facet type `W` is partially identified as soon as it is declared. +// Converting from a facet requires its facet type to be at least partially +// identified, not fully identified. +constraint W; + +fn F(T:! W & Z) { + T as Z; +} diff --git a/toolchain/check/testdata/facet/require_constrains_self.carbon b/toolchain/check/testdata/facet/require_constrains_self.carbon deleted file mode 100644 index e391a590bc55..000000000000 --- a/toolchain/check/testdata/facet/require_constrains_self.carbon +++ /dev/null @@ -1,66 +0,0 @@ -// 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 -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/require_constrains_self.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/require_constrains_self.carbon - -// --- fail_self_doesnt_meet_constraint.carbon -library "[[@TEST_NAME]]"; - -interface Y2 {} -interface Y(T:! Y2) {} -// TODO: The error should be that Self does not implement Y2, not that it can't -// be identified. We should allow identifying `Self`. -// -// CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE+17]]:37: error: facet type of value `Self` can not be identified [ImplLookupInUnidentifiedFacetTypeOfQuerySelf] -// CHECK:STDERR: constraint W { extend require impls Y(Self); } -// CHECK:STDERR: ^~~~~~~ -// CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE+14]]:1: note: constraint is currently being defined [NamedConstraintIncompleteWithinDefinition] -// CHECK:STDERR: constraint W { extend require impls Y(Self); } -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE-10]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] -// CHECK:STDERR: interface Y(T:! Y2) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE+7]]:37: error: cannot convert type `Self` that implements `W` into type implementing `Y2` [ConversionFailureFacetToFacet] -// CHECK:STDERR: constraint W { extend require impls Y(Self); } -// CHECK:STDERR: ^~~~~~~ -// CHECK:STDERR: fail_self_doesnt_meet_constraint.carbon:[[@LINE-17]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] -// CHECK:STDERR: interface Y(T:! Y2) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -constraint W { extend require impls Y(Self); } - -// --- fail_todo_self_meets_constraint.carbon -library "[[@TEST_NAME]]"; - -interface Y2 {} -interface Y(T:! Y2) {} -constraint W { - // TODO: This should allow the next line to work, as Self should be known to impl Y2. - require impls Y2; - // CHECK:STDERR: fail_todo_self_meets_constraint.carbon:[[@LINE+17]]:24: error: facet type of value `Self` can not be identified [ImplLookupInUnidentifiedFacetTypeOfQuerySelf] - // CHECK:STDERR: extend require impls Y(Self); - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: fail_todo_self_meets_constraint.carbon:[[@LINE-6]]:1: note: constraint is currently being defined [NamedConstraintIncompleteWithinDefinition] - // CHECK:STDERR: constraint W { - // CHECK:STDERR: ^~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_self_meets_constraint.carbon:[[@LINE-10]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] - // CHECK:STDERR: interface Y(T:! Y2) {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_self_meets_constraint.carbon:[[@LINE+7]]:24: error: cannot convert type `Self` that implements `W` into type implementing `Y2` [ConversionFailureFacetToFacet] - // CHECK:STDERR: extend require impls Y(Self); - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: fail_todo_self_meets_constraint.carbon:[[@LINE-17]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] - // CHECK:STDERR: interface Y(T:! Y2) {} - // CHECK:STDERR: ^ - // CHECK:STDERR: - extend require impls Y(Self); -} diff --git a/toolchain/check/testdata/facet/require_invalid.carbon b/toolchain/check/testdata/facet/require_invalid.carbon index 28dedb4235ad..88e138b7f931 100644 --- a/toolchain/check/testdata/facet/require_invalid.carbon +++ b/toolchain/check/testdata/facet/require_invalid.carbon @@ -192,3 +192,20 @@ interface Z { Self.A; } } + +// --- todo_fail_impl_mismatch_named_constraint_rewrites.carbon +library "[[@TEST_NAME]]"; + +interface Z { let Z0:! type; } + +constraint M { + require impls Z where .Z0 = {}; +} + +fn G() { + class C {} + // .Z0 has the wrong type for M. + impl C as Z where .Z0 = () {} + // TODO: Converting C to M should fail since the rewrite constraints are incompatible. + C as M; +} diff --git a/toolchain/check/testdata/for/actual.carbon b/toolchain/check/testdata/for/actual.carbon index 7f981a9f97d3..238a12a1d212 100644 --- a/toolchain/check/testdata/for/actual.carbon +++ b/toolchain/check/testdata/for/actual.carbon @@ -83,30 +83,30 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %Optional.None.type.fc5: type = fn_type @Optional.None, @Optional(%T.542) [symbolic] // CHECK:STDOUT: %Optional.None.fcb: %Optional.None.type.fc5 = struct_value () [symbolic] // CHECK:STDOUT: %.Self.2b2: %Iterate.type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %Iterate.lookup_impl_witness.53f: = lookup_impl_witness %.Self.2b2, @Iterate [symbolic_self] -// CHECK:STDOUT: %impl.elem0.3b1: %facet_type.7e2 = impl_witness_access %Iterate.lookup_impl_witness.53f, element0 [symbolic_self] // CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self.2b2 [symbolic_self] // CHECK:STDOUT: %Iterate.assoc_type: type = assoc_entity_type @Iterate [concrete] // CHECK:STDOUT: %assoc1.a27: %Iterate.assoc_type = assoc_entity element1, imports.%Core.import_ref.cd6 [concrete] +// CHECK:STDOUT: %Iterate.lookup_impl_witness.53f: = lookup_impl_witness %.Self.2b2, @Iterate [symbolic_self] // CHECK:STDOUT: %impl.elem1.49e: type = impl_witness_access %Iterate.lookup_impl_witness.53f, element1 [symbolic_self] // CHECK:STDOUT: %assoc0.4bd: %Iterate.assoc_type = assoc_entity element0, imports.%Core.import_ref.f74 [concrete] +// CHECK:STDOUT: %impl.elem0.3b1: %facet_type.7e2 = impl_witness_access %Iterate.lookup_impl_witness.53f, element0 [symbolic_self] // CHECK:STDOUT: %Destroy.lookup_impl_witness.93c: = lookup_impl_witness %Int.fc6021.1, @Destroy [symbolic] // CHECK:STDOUT: %require_complete.9019d7.1: = require_complete_type %Int.fc6021.1 [symbolic] // CHECK:STDOUT: %Int.as.Copy.impl.Op.type.824: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] // CHECK:STDOUT: %Int.as.Copy.impl.Op.9b9: %Int.as.Copy.impl.Op.type.824 = struct_value () [symbolic] // CHECK:STDOUT: %.83cba3.1: Core.Form = init_form %Int.fc6021.1 [symbolic] -// CHECK:STDOUT: %.4f8: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.7a8: = lookup_impl_witness %Int.fc6021.1, @Copy [symbolic] +// CHECK:STDOUT: %.4f8: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic] // CHECK:STDOUT: %facet_value: %facet_type.7e2 = facet_value %Int.fc6021.1, (%Destroy.lookup_impl_witness.93c, %Copy.lookup_impl_witness.7a8) [symbolic] -// CHECK:STDOUT: %Iterate_where.type: type = facet_type <@Iterate where %impl.elem0.3b1 = %facet_value and %impl.elem1.49e = %Int.fc6021.1> [symbolic] +// CHECK:STDOUT: %Iterate_where.type: type = facet_type <@Iterate where %impl.elem1.49e = %Int.fc6021.1 and %impl.elem0.3b1 = %facet_value> [symbolic] // CHECK:STDOUT: %Iterate.impl_witness: = impl_witness @IntRange.as.Iterate.impl.%Iterate.impl_witness_table, @IntRange.as.Iterate.impl(%N) [symbolic] -// CHECK:STDOUT: %require_complete.234: = require_complete_type %Iterate_where.type [symbolic] +// CHECK:STDOUT: %require_complete.63d: = require_complete_type %Iterate_where.type [symbolic] // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor.type: type = fn_type @IntRange.as.Iterate.impl.NewCursor, @IntRange.as.Iterate.impl(%N) [symbolic] // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor: %IntRange.as.Iterate.impl.NewCursor.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.c9c: type = ptr_type %Int.fc6021.1 [symbolic] // CHECK:STDOUT: %pattern_type.bda: type = pattern_type %ptr.c9c [symbolic] -// CHECK:STDOUT: %.63c: require_specific_def_type = require_specific_def @T.binding.as_type.as.OptionalStorage.impl(%facet_value) [symbolic] // CHECK:STDOUT: %OptionalStorage.lookup_impl_witness.b62: = lookup_impl_witness %Int.fc6021.1, @OptionalStorage [symbolic] +// CHECK:STDOUT: %.63c: require_specific_def_type = require_specific_def @T.binding.as_type.as.OptionalStorage.impl(%facet_value) [symbolic] // CHECK:STDOUT: %OptionalStorage.facet.01e: %OptionalStorage.type = facet_value %Int.fc6021.1, (%OptionalStorage.lookup_impl_witness.b62) [symbolic] // CHECK:STDOUT: %Optional.e48: type = class_type @Optional, @Optional(%OptionalStorage.facet.01e) [symbolic] // CHECK:STDOUT: %.949: Core.Form = init_form %Optional.e48 [symbolic] @@ -155,8 +155,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %.48d: type = fn_type_with_self_type %OrderedWith.WithSelf.Less.type.3a2, %OrderedWith.facet [symbolic] // CHECK:STDOUT: %Int.as.OrderedWith.impl.Less.specific_fn.4c2: = specific_function %Int.as.OrderedWith.impl.Less.4cf, @Int.as.OrderedWith.impl.Less.1(%N, %N) [symbolic] // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] -// CHECK:STDOUT: %.53b: require_specific_def_type = require_specific_def @Int.as.Inc.impl(%N) [symbolic] // CHECK:STDOUT: %Inc.lookup_impl_witness: = lookup_impl_witness %Int.fc6021.1, @Inc [symbolic] +// CHECK:STDOUT: %.53b: require_specific_def_type = require_specific_def @Int.as.Inc.impl(%N) [symbolic] // CHECK:STDOUT: %Inc.facet: %Inc.type = facet_value %Int.fc6021.1, (%Inc.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Inc.WithSelf.Op.type.17b: type = fn_type @Inc.WithSelf.Op, @Inc.WithSelf(%Inc.facet) [symbolic] // CHECK:STDOUT: %.9a6: type = fn_type_with_self_type %Inc.WithSelf.Op.type.17b, %Inc.facet [symbolic] @@ -181,10 +181,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %IntRange.Make.type.045: type = fn_type @IntRange.Make, @IntRange(%int_32) [concrete] // CHECK:STDOUT: %IntRange.Make.3e9: %IntRange.Make.type.045 = struct_value () [concrete] -// CHECK:STDOUT: %Copy.impl_witness.f17: = impl_witness imports.%Copy.impl_witness_table.e76, @Int.as.Copy.impl(%int_32) [concrete] -// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.546: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] -// CHECK:STDOUT: %Int.as.Copy.impl.Op.664: %Int.as.Copy.impl.Op.type.546 = struct_value () [concrete] -// CHECK:STDOUT: %.14e: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%int_32) [concrete] // CHECK:STDOUT: %IntRange.elem.a58: type = unbound_element_type %IntRange.a89, %i32 [concrete] // CHECK:STDOUT: %struct_type.start.end.d0a: type = struct_type {.start: %i32, .end: %i32} [concrete] // CHECK:STDOUT: %complete_type.c45: = complete_type_witness %struct_type.start.end.d0a [concrete] @@ -204,6 +200,10 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] +// CHECK:STDOUT: %Copy.impl_witness.f17: = impl_witness imports.%Copy.impl_witness_table.e76, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.546: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.664: %Int.as.Copy.impl.Op.type.546 = struct_value () [concrete] +// CHECK:STDOUT: %.14e: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%int_32) [concrete] // CHECK:STDOUT: %Copy.facet.de4: %Copy.type = facet_value %i32, (%Copy.impl_witness.f17) [concrete] // CHECK:STDOUT: %Copy.WithSelf.Op.type.081: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.de4) [concrete] // CHECK:STDOUT: %.8e2: type = fn_type_with_self_type %Copy.WithSelf.Op.type.081, %Copy.facet.de4 [concrete] @@ -298,17 +298,16 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %IntRange: type = class_type @IntRange, @IntRange(%N) [symbolic = %IntRange (constants.%IntRange.265)] // CHECK:STDOUT: %Int.loc9_54.1: type = class_type @Int, @Int(%N) [symbolic = %Int.loc9_54.1 (constants.%Int.fc6021.1)] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Int.loc9_54.1, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.93c)] -// CHECK:STDOUT: %.loc9_85.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc9_85.1 (constants.%.4f8)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %Int.loc9_54.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.7a8)] +// CHECK:STDOUT: %.loc9_85.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc9_85.1 (constants.%.4f8)] // CHECK:STDOUT: %facet_value.loc9_85.1: %facet_type.7e2 = facet_value %Int.loc9_54.1, (%Destroy.lookup_impl_witness, %Copy.lookup_impl_witness) [symbolic = %facet_value.loc9_85.1 (constants.%facet_value)] -// CHECK:STDOUT: %Iterate_where.type: type = facet_type <@Iterate where constants.%impl.elem0.3b1 = %facet_value.loc9_85.1 and constants.%impl.elem1.49e = %Int.loc9_54.1> [symbolic = %Iterate_where.type (constants.%Iterate_where.type)] +// CHECK:STDOUT: %Iterate_where.type: type = facet_type <@Iterate where constants.%impl.elem1.49e = %Int.loc9_54.1 and constants.%impl.elem0.3b1 = %facet_value.loc9_85.1> [symbolic = %Iterate_where.type (constants.%Iterate_where.type)] // CHECK:STDOUT: %Iterate.impl_witness.loc9_87.2: = impl_witness %Iterate.impl_witness_table, @IntRange.as.Iterate.impl(%N) [symbolic = %Iterate.impl_witness.loc9_87.2 (constants.%Iterate.impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %Iterate_where.type [symbolic = %require_complete (constants.%require_complete.234)] +// CHECK:STDOUT: %require_complete: = require_complete_type %Iterate_where.type [symbolic = %require_complete (constants.%require_complete.63d)] // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor.type: type = fn_type @IntRange.as.Iterate.impl.NewCursor, @IntRange.as.Iterate.impl(%N) [symbolic = %IntRange.as.Iterate.impl.NewCursor.type (constants.%IntRange.as.Iterate.impl.NewCursor.type)] // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor: @IntRange.as.Iterate.impl.%IntRange.as.Iterate.impl.NewCursor.type (%IntRange.as.Iterate.impl.NewCursor.type) = struct_value () [symbolic = %IntRange.as.Iterate.impl.NewCursor (constants.%IntRange.as.Iterate.impl.NewCursor)] -// CHECK:STDOUT: %.loc11: require_specific_def_type = require_specific_def @T.binding.as_type.as.OptionalStorage.impl(%facet_value.loc9_85.1) [symbolic = %.loc11 (constants.%.63c)] // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next.type: type = fn_type @IntRange.as.Iterate.impl.Next, @IntRange.as.Iterate.impl(%N) [symbolic = %IntRange.as.Iterate.impl.Next.type (constants.%IntRange.as.Iterate.impl.Next.type)] // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next: @IntRange.as.Iterate.impl.%IntRange.as.Iterate.impl.Next.type (%IntRange.as.Iterate.impl.Next.type) = struct_value () [symbolic = %IntRange.as.Iterate.impl.Next (constants.%IntRange.as.Iterate.impl.Next)] // CHECK:STDOUT: @@ -369,10 +368,10 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %return.param: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.e48) = out_param call_param2 // CHECK:STDOUT: %return: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.e48) = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %Iterate.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant.loc9_87.1, %impl_witness_assoc_constant.loc9_87.2, %IntRange.as.Iterate.impl.NewCursor.decl, %IntRange.as.Iterate.impl.Next.decl), @IntRange.as.Iterate.impl [concrete] +// CHECK:STDOUT: %Iterate.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant.loc9_87.2, %impl_witness_assoc_constant.loc9_87.1, %IntRange.as.Iterate.impl.NewCursor.decl, %IntRange.as.Iterate.impl.Next.decl), @IntRange.as.Iterate.impl [concrete] // CHECK:STDOUT: %Iterate.impl_witness.loc9_87.1: = impl_witness %Iterate.impl_witness_table, @IntRange.as.Iterate.impl(constants.%N) [symbolic = %Iterate.impl_witness.loc9_87.2 (constants.%Iterate.impl_witness)] -// CHECK:STDOUT: %impl_witness_assoc_constant.loc9_87.1: %facet_type.7e2 = impl_witness_assoc_constant constants.%facet_value [symbolic = %facet_value.loc9_85.1 (constants.%facet_value)] -// CHECK:STDOUT: %impl_witness_assoc_constant.loc9_87.2: type = impl_witness_assoc_constant constants.%Int.fc6021.1 [symbolic = %Int.loc9_54.1 (constants.%Int.fc6021.1)] +// CHECK:STDOUT: %impl_witness_assoc_constant.loc9_87.1: type = impl_witness_assoc_constant constants.%Int.fc6021.1 [symbolic = %Int.loc9_54.1 (constants.%Int.fc6021.1)] +// CHECK:STDOUT: %impl_witness_assoc_constant.loc9_87.2: %facet_type.7e2 = impl_witness_assoc_constant constants.%facet_value [symbolic = %facet_value.loc9_85.1 (constants.%facet_value)] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .N = @@ -388,7 +387,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type: type = fn_type @IntRange.Make, @IntRange(%N.loc4_16.1) [symbolic = %IntRange.Make.type (constants.%IntRange.Make.type.1df)] // CHECK:STDOUT: %IntRange.Make: @IntRange.%IntRange.Make.type (%IntRange.Make.type.1df) = struct_value () [symbolic = %IntRange.Make (constants.%IntRange.Make.8a9)] -// CHECK:STDOUT: %.loc9: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N.loc4_16.1) [symbolic = %.loc9 (constants.%.4f8)] // CHECK:STDOUT: %Int.loc22_32.2: type = class_type @Int, @Int(%N.loc4_16.1) [symbolic = %Int.loc22_32.2 (constants.%Int.fc6021.1)] // CHECK:STDOUT: %require_complete: = require_complete_type %Int.loc22_32.2 [symbolic = %require_complete (constants.%require_complete.9019d7.1)] // CHECK:STDOUT: %IntRange: type = class_type @IntRange, @IntRange(%N.loc4_16.1) [symbolic = %IntRange (constants.%IntRange.265)] @@ -492,8 +490,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %require_complete.loc5_16: = require_complete_type %Int.loc5_28.1 [symbolic = %require_complete.loc5_16 (constants.%require_complete.9019d7.1)] // CHECK:STDOUT: %require_complete.loc5_52: = require_complete_type %IntRange [symbolic = %require_complete.loc5_52 (constants.%require_complete.8a1)] // CHECK:STDOUT: %struct_type.start.end: type = struct_type {.start: @IntRange.Make.%Int.loc5_28.1 (%Int.fc6021.1), .end: @IntRange.Make.%Int.loc5_28.1 (%Int.fc6021.1)} [symbolic = %struct_type.start.end (constants.%struct_type.start.end.ff1)] -// CHECK:STDOUT: %.loc6_22.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc6_22.1 (constants.%.4f8)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %Int.loc5_28.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.7a8)] +// CHECK:STDOUT: %.loc6_22.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc6_22.1 (constants.%.4f8)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %Int.loc5_28.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.3b9)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.e13)] // CHECK:STDOUT: %.loc6_22.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc6_22.2 (constants.%.e29)] @@ -537,8 +535,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %require_complete.loc10_22: = require_complete_type %IntRange [symbolic = %require_complete.loc10_22 (constants.%require_complete.8a1)] // CHECK:STDOUT: %IntRange.elem: type = unbound_element_type %IntRange, %Int.loc10_45.1 [symbolic = %IntRange.elem (constants.%IntRange.elem.541)] // CHECK:STDOUT: %require_complete.loc10_60: = require_complete_type %Int.loc10_45.1 [symbolic = %require_complete.loc10_60 (constants.%require_complete.9019d7.1)] -// CHECK:STDOUT: %.loc10_60.3: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc10_60.3 (constants.%.4f8)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %Int.loc10_45.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.7a8)] +// CHECK:STDOUT: %.loc10_60.3: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.loc10_60.3 (constants.%.4f8)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %Int.loc10_45.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.3b9)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.e13)] // CHECK:STDOUT: %.loc10_60.4: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc10_60.4 (constants.%.e29)] @@ -567,11 +565,11 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %Int.loc11_43.1: type = class_type @Int, @Int(%N) [symbolic = %Int.loc11_43.1 (constants.%Int.fc6021.1)] // CHECK:STDOUT: %ptr.loc11_44.1: type = ptr_type %Int.loc11_43.1 [symbolic = %ptr.loc11_44.1 (constants.%ptr.c9c)] // CHECK:STDOUT: %pattern_type.loc11_31: type = pattern_type %ptr.loc11_44.1 [symbolic = %pattern_type.loc11_31 (constants.%pattern_type.bda)] +// CHECK:STDOUT: %OptionalStorage.lookup_impl_witness: = lookup_impl_witness %Int.loc11_43.1, @OptionalStorage [symbolic = %OptionalStorage.lookup_impl_witness (constants.%OptionalStorage.lookup_impl_witness.b62)] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Int.loc11_43.1, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.93c)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %Int.loc11_43.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.7a8)] // CHECK:STDOUT: %facet_value: %facet_type.7e2 = facet_value %Int.loc11_43.1, (%Destroy.lookup_impl_witness, %Copy.lookup_impl_witness) [symbolic = %facet_value (constants.%facet_value)] // CHECK:STDOUT: %.loc11_75.3: require_specific_def_type = require_specific_def @T.binding.as_type.as.OptionalStorage.impl(%facet_value) [symbolic = %.loc11_75.3 (constants.%.63c)] -// CHECK:STDOUT: %OptionalStorage.lookup_impl_witness: = lookup_impl_witness %Int.loc11_43.1, @OptionalStorage [symbolic = %OptionalStorage.lookup_impl_witness (constants.%OptionalStorage.lookup_impl_witness.b62)] // CHECK:STDOUT: %OptionalStorage.facet.loc11_75.1: %OptionalStorage.type = facet_value %Int.loc11_43.1, (%OptionalStorage.lookup_impl_witness) [symbolic = %OptionalStorage.facet.loc11_75.1 (constants.%OptionalStorage.facet.01e)] // CHECK:STDOUT: %Optional.loc11_75.1: type = class_type @Optional, @Optional(%OptionalStorage.facet.loc11_75.1) [symbolic = %Optional.loc11_75.1 (constants.%Optional.e48)] // CHECK:STDOUT: %.loc11_75.4: Core.Form = init_form %Optional.loc11_75.1 [symbolic = %.loc11_75.4 (constants.%.949)] @@ -602,8 +600,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %Int.as.OrderedWith.impl.Less.type: type = fn_type @Int.as.OrderedWith.impl.Less.1, @Int.as.OrderedWith.impl.2e6(%N, %N) [symbolic = %Int.as.OrderedWith.impl.Less.type (constants.%Int.as.OrderedWith.impl.Less.type.3f1)] // CHECK:STDOUT: %Int.as.OrderedWith.impl.Less: @IntRange.as.Iterate.impl.Next.%Int.as.OrderedWith.impl.Less.type (%Int.as.OrderedWith.impl.Less.type.3f1) = struct_value () [symbolic = %Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.4cf)] // CHECK:STDOUT: %Int.as.OrderedWith.impl.Less.specific_fn: = specific_function %Int.as.OrderedWith.impl.Less, @Int.as.OrderedWith.impl.Less.1(%N, %N) [symbolic = %Int.as.OrderedWith.impl.Less.specific_fn (constants.%Int.as.OrderedWith.impl.Less.specific_fn.4c2)] -// CHECK:STDOUT: %.loc14_9.1: require_specific_def_type = require_specific_def @Int.as.Inc.impl(%N) [symbolic = %.loc14_9.1 (constants.%.53b)] // CHECK:STDOUT: %Inc.lookup_impl_witness: = lookup_impl_witness %Int.loc11_43.1, @Inc [symbolic = %Inc.lookup_impl_witness (constants.%Inc.lookup_impl_witness)] +// CHECK:STDOUT: %.loc14_9.1: require_specific_def_type = require_specific_def @Int.as.Inc.impl(%N) [symbolic = %.loc14_9.1 (constants.%.53b)] // CHECK:STDOUT: %Inc.facet: %Inc.type = facet_value %Int.loc11_43.1, (%Inc.lookup_impl_witness) [symbolic = %Inc.facet (constants.%Inc.facet)] // CHECK:STDOUT: %Inc.WithSelf.Op.type: type = fn_type @Inc.WithSelf.Op, @Inc.WithSelf(%Inc.facet) [symbolic = %Inc.WithSelf.Op.type (constants.%Inc.WithSelf.Op.type.17b)] // CHECK:STDOUT: %.loc14_9.2: type = fn_type_with_self_type %Inc.WithSelf.Op.type, %Inc.facet [symbolic = %.loc14_9.2 (constants.%.9a6)] @@ -747,7 +745,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type => constants.%IntRange.Make.type.1df // CHECK:STDOUT: %IntRange.Make => constants.%IntRange.Make.8a9 -// CHECK:STDOUT: %.loc9 => constants.%.4f8 // CHECK:STDOUT: %Int.loc22_32.2 => constants.%Int.fc6021.1 // CHECK:STDOUT: %require_complete => constants.%require_complete.9019d7.1 // CHECK:STDOUT: %IntRange => constants.%IntRange.265 @@ -770,17 +767,16 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %IntRange => constants.%IntRange.265 // CHECK:STDOUT: %Int.loc9_54.1 => constants.%Int.fc6021.1 // CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.lookup_impl_witness.93c -// CHECK:STDOUT: %.loc9_85.1 => constants.%.4f8 // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.7a8 +// CHECK:STDOUT: %.loc9_85.1 => constants.%.4f8 // CHECK:STDOUT: %facet_value.loc9_85.1 => constants.%facet_value // CHECK:STDOUT: %Iterate_where.type => constants.%Iterate_where.type // CHECK:STDOUT: %Iterate.impl_witness.loc9_87.2 => constants.%Iterate.impl_witness // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%require_complete.234 +// CHECK:STDOUT: %require_complete => constants.%require_complete.63d // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor.type => constants.%IntRange.as.Iterate.impl.NewCursor.type // CHECK:STDOUT: %IntRange.as.Iterate.impl.NewCursor => constants.%IntRange.as.Iterate.impl.NewCursor -// CHECK:STDOUT: %.loc11 => constants.%.63c // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next.type => constants.%IntRange.as.Iterate.impl.Next.type // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next => constants.%IntRange.as.Iterate.impl.Next // CHECK:STDOUT: } @@ -801,11 +797,11 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %Int.loc11_43.1 => constants.%Int.fc6021.1 // CHECK:STDOUT: %ptr.loc11_44.1 => constants.%ptr.c9c // CHECK:STDOUT: %pattern_type.loc11_31 => constants.%pattern_type.bda +// CHECK:STDOUT: %OptionalStorage.lookup_impl_witness => constants.%OptionalStorage.lookup_impl_witness.b62 // CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.lookup_impl_witness.93c // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.7a8 // CHECK:STDOUT: %facet_value => constants.%facet_value // CHECK:STDOUT: %.loc11_75.3 => constants.%.63c -// CHECK:STDOUT: %OptionalStorage.lookup_impl_witness => constants.%OptionalStorage.lookup_impl_witness.b62 // CHECK:STDOUT: %OptionalStorage.facet.loc11_75.1 => constants.%OptionalStorage.facet.01e // CHECK:STDOUT: %Optional.loc11_75.1 => constants.%Optional.e48 // CHECK:STDOUT: %.loc11_75.4 => constants.%.949 @@ -818,7 +814,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type => constants.%IntRange.Make.type.045 // CHECK:STDOUT: %IntRange.Make => constants.%IntRange.Make.3e9 -// CHECK:STDOUT: %.loc9 => constants.%.14e // CHECK:STDOUT: %Int.loc22_32.2 => constants.%i32 // CHECK:STDOUT: %require_complete => constants.%complete_type.f8a // CHECK:STDOUT: %IntRange => constants.%IntRange.a89 @@ -839,8 +834,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %require_complete.loc5_16 => constants.%complete_type.f8a // CHECK:STDOUT: %require_complete.loc5_52 => constants.%complete_type.c45 // CHECK:STDOUT: %struct_type.start.end => constants.%struct_type.start.end.d0a -// CHECK:STDOUT: %.loc6_22.1 => constants.%.14e // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.f17 +// CHECK:STDOUT: %.loc6_22.1 => constants.%.14e // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.de4 // CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.081 // CHECK:STDOUT: %.loc6_22.2 => constants.%.8e2 @@ -869,19 +864,19 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %IntRange.265: type = class_type @IntRange, @IntRange(%N) [symbolic] // CHECK:STDOUT: %IntRange.elem.302: type = unbound_element_type %IntRange.265, %Int.b6d943.1 [symbolic] // CHECK:STDOUT: %require_complete.2ded7d.1: = require_complete_type %Int.b6d943.1 [symbolic] -// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %pattern_type.bb68b6.1: type = pattern_type %Int.b6d943.1 [symbolic] -// CHECK:STDOUT: %.b26: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic] // CHECK:STDOUT: %IntRange.Make.type.1df: type = fn_type @IntRange.Make, @IntRange(%N) [symbolic] // CHECK:STDOUT: %IntRange.Make.8a9: %IntRange.Make.type.1df = struct_value () [symbolic] // CHECK:STDOUT: %pattern_type.b16: type = pattern_type %IntRange.265 [symbolic] // CHECK:STDOUT: %.e1e: Core.Form = init_form %IntRange.265 [symbolic] +// CHECK:STDOUT: %pattern_type.bb68b6.1: type = pattern_type %Int.b6d943.1 [symbolic] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %Copy.lookup_impl_witness.4c7: = lookup_impl_witness %Int.b6d943.1, @Copy [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %Int.b6d943.1, (%Copy.lookup_impl_witness.4c7) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.2e7: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.cf8: type = fn_type_with_self_type %Copy.WithSelf.Op.type.2e7, %Copy.facet [symbolic] // CHECK:STDOUT: %impl.elem0.84f: %.cf8 = impl_witness_access %Copy.lookup_impl_witness.4c7, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn.508: = specific_impl_function %impl.elem0.84f, @Copy.WithSelf.Op(%Copy.facet) [symbolic] +// CHECK:STDOUT: %.b26: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic] // CHECK:STDOUT: %require_complete.8a1: = require_complete_type %IntRange.265 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %IntRange.a89: type = class_type @IntRange, @IntRange(%int_32) [concrete] @@ -890,7 +885,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] -// CHECK:STDOUT: %.fc8: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%int_32) [concrete] // CHECK:STDOUT: %IntRange.elem.d76: type = unbound_element_type %IntRange.a89, %i32 [concrete] // CHECK:STDOUT: %struct_type.start.end.0fe: type = struct_type {.start: %i32, .end: %i32} [concrete] // CHECK:STDOUT: %complete_type.a43: = complete_type_witness %struct_type.start.end.0fe [concrete] @@ -972,7 +966,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type: type = fn_type @IntRange.Make, @IntRange(%N) [symbolic = %IntRange.Make.type (constants.%IntRange.Make.type.1df)] // CHECK:STDOUT: %IntRange.Make: @IntRange.%IntRange.Make.type (%IntRange.Make.type.1df) = struct_value () [symbolic = %IntRange.Make (constants.%IntRange.Make.8a9)] -// CHECK:STDOUT: %.1: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.1 (constants.%.b26)] // CHECK:STDOUT: %Int: type = class_type @Int, @Int(%N) [symbolic = %Int (constants.%Int.b6d943.1)] // CHECK:STDOUT: %require_complete: = require_complete_type %Int [symbolic = %require_complete (constants.%require_complete.2ded7d.1)] // CHECK:STDOUT: %IntRange: type = class_type @IntRange, @IntRange(%N) [symbolic = %IntRange (constants.%IntRange.265)] @@ -1042,8 +1035,8 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: %require_complete.1: = require_complete_type %Int [symbolic = %require_complete.1 (constants.%require_complete.2ded7d.1)] // CHECK:STDOUT: %require_complete.2: = require_complete_type %IntRange [symbolic = %require_complete.2 (constants.%require_complete.8a1)] // CHECK:STDOUT: %struct_type.start.end: type = struct_type {.start: @IntRange.Make.%Int (%Int.b6d943.1), .end: @IntRange.Make.%Int (%Int.b6d943.1)} [symbolic = %struct_type.start.end (constants.%struct_type.start.end.79a)] -// CHECK:STDOUT: %.2: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.2 (constants.%.b26)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %Int, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.4c7)] +// CHECK:STDOUT: %.2: require_specific_def_type = require_specific_def @Int.as.Copy.impl(%N) [symbolic = %.2 (constants.%.b26)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %Int, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.2e7)] // CHECK:STDOUT: %.3: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.3 (constants.%.cf8)] @@ -1067,7 +1060,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type => constants.%IntRange.Make.type.1df // CHECK:STDOUT: %IntRange.Make => constants.%IntRange.Make.8a9 -// CHECK:STDOUT: %.1 => constants.%.b26 // CHECK:STDOUT: %Int => constants.%Int.b6d943.1 // CHECK:STDOUT: %require_complete => constants.%require_complete.2ded7d.1 // CHECK:STDOUT: %IntRange => constants.%IntRange.265 @@ -1091,7 +1083,6 @@ fn Read(y:! Core.IntLiteral()) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %IntRange.Make.type => constants.%IntRange.Make.type.045 // CHECK:STDOUT: %IntRange.Make => constants.%IntRange.Make.3e9 -// CHECK:STDOUT: %.1 => constants.%.fc8 // CHECK:STDOUT: %Int => constants.%i32 // CHECK:STDOUT: %require_complete => constants.%complete_type.f8a // CHECK:STDOUT: %IntRange => constants.%IntRange.a89 diff --git a/toolchain/check/testdata/function/generic/call.carbon b/toolchain/check/testdata/function/generic/call.carbon index d3efc0769dbb..7726962a5579 100644 --- a/toolchain/check/testdata/function/generic/call.carbon +++ b/toolchain/check/testdata/function/generic/call.carbon @@ -95,8 +95,8 @@ fn CallSpecific(x: C*) -> C* { // CHECK:STDOUT: %pattern_type.4f4: type = pattern_type %ptr.e8f [symbolic] // CHECK:STDOUT: %.cb6: Core.Form = init_form %ptr.e8f [symbolic] // CHECK:STDOUT: %Function.specific_fn.a87: = specific_function %Function, @Function(%T.035) [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Function.specific_fn.919: = specific_function %Function, @Function(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -211,8 +211,8 @@ fn CallSpecific(x: C*) -> C* { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc18_24.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc16_19.1) [symbolic = %.loc18_24.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc16_33.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc18_24.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc16_19.1) [symbolic = %.loc18_24.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet.loc18_24.3: %Copy.type = facet_value %ptr.loc16_33.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc18_24.3 (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Function.specific_fn.loc18_10.2: = specific_function constants.%Function, @Function(%Copy.facet.loc18_24.3) [symbolic = %Function.specific_fn.loc18_10.2 (constants.%Function.specific_fn.919)] // CHECK:STDOUT: @@ -331,8 +331,8 @@ fn CallSpecific(x: C*) -> C* { // CHECK:STDOUT: %pattern_type.4f4: type = pattern_type %ptr.e8f [symbolic] // CHECK:STDOUT: %.cb6: Core.Form = init_form %ptr.e8f [symbolic] // CHECK:STDOUT: %Function.specific_fn.a87: = specific_function %Function, @Function(%T.035) [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Function.specific_fn.919: = specific_function %Function, @Function(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -446,8 +446,8 @@ fn CallSpecific(x: C*) -> C* { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc18_20.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc16_19.1) [symbolic = %.loc18_20.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc16_33.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc18_20.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc16_19.1) [symbolic = %.loc18_20.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet.loc18_20.2: %Copy.type = facet_value %ptr.loc16_33.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc18_20.2 (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Function.specific_fn.loc18_10.2: = specific_function constants.%Function, @Function(%Copy.facet.loc18_20.2) [symbolic = %Function.specific_fn.loc18_10.2 (constants.%Function.specific_fn.919)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/generic/deduce.carbon b/toolchain/check/testdata/function/generic/deduce.carbon index 1f21c66bacf8..8de4de05ea92 100644 --- a/toolchain/check/testdata/function/generic/deduce.carbon +++ b/toolchain/check/testdata/function/generic/deduce.carbon @@ -1672,8 +1672,8 @@ fn F() { // CHECK:STDOUT: %CC.type: type = generic_class_type @CC [concrete] // CHECK:STDOUT: %CC.generic: %CC.type = struct_value () [concrete] // CHECK:STDOUT: %CC.a1b: type = class_type @CC, @CC(%D) [symbolic] -// CHECK:STDOUT: %.bf4: require_specific_def_type = require_specific_def @DD.as.Z.impl(%E) [symbolic] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %DD.a29, @Z [symbolic] +// CHECK:STDOUT: %.bf4: require_specific_def_type = require_specific_def @DD.as.Z.impl(%E) [symbolic] // CHECK:STDOUT: %Z.facet.892: %Z.type = facet_value %DD.a29, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %CC.4e1: type = class_type @CC, @CC(%Z.facet.892) [symbolic] // CHECK:STDOUT: %Z.impl_witness.40e: = impl_witness @CC.as.Z.impl.%Z.impl_witness_table, @CC.as.Z.impl(%E) [symbolic] @@ -1801,8 +1801,8 @@ fn F() { // CHECK:STDOUT: generic impl @CC.as.Z.impl(%E.loc12_14.1: type) { // CHECK:STDOUT: %E.loc12_14.2: type = symbolic_binding E, 0 [symbolic = %E.loc12_14.2 (constants.%E)] // CHECK:STDOUT: %DD.loc12_31.2: type = class_type @DD, @DD(%E.loc12_14.2) [symbolic = %DD.loc12_31.2 (constants.%DD.a29)] -// CHECK:STDOUT: %.loc12_32.2: require_specific_def_type = require_specific_def @DD.as.Z.impl(%E.loc12_14.2) [symbolic = %.loc12_32.2 (constants.%.bf4)] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %DD.loc12_31.2, @Z [symbolic = %Z.lookup_impl_witness (constants.%Z.lookup_impl_witness)] +// CHECK:STDOUT: %.loc12_32.2: require_specific_def_type = require_specific_def @DD.as.Z.impl(%E.loc12_14.2) [symbolic = %.loc12_32.2 (constants.%.bf4)] // CHECK:STDOUT: %Z.facet.loc12_32.2: %Z.type = facet_value %DD.loc12_31.2, (%Z.lookup_impl_witness) [symbolic = %Z.facet.loc12_32.2 (constants.%Z.facet.892)] // CHECK:STDOUT: %CC.loc12_32.2: type = class_type @CC, @CC(%Z.facet.loc12_32.2) [symbolic = %CC.loc12_32.2 (constants.%CC.4e1)] // CHECK:STDOUT: %Z.impl_witness.loc12_39.2: = impl_witness %Z.impl_witness_table, @CC.as.Z.impl(%E.loc12_14.2) [symbolic = %Z.impl_witness.loc12_39.2 (constants.%Z.impl_witness.40e)] @@ -1904,8 +1904,8 @@ fn F() { // CHECK:STDOUT: specific @CC.as.Z.impl(constants.%E) { // CHECK:STDOUT: %E.loc12_14.2 => constants.%E // CHECK:STDOUT: %DD.loc12_31.2 => constants.%DD.a29 -// CHECK:STDOUT: %.loc12_32.2 => constants.%.bf4 // CHECK:STDOUT: %Z.lookup_impl_witness => constants.%Z.lookup_impl_witness +// CHECK:STDOUT: %.loc12_32.2 => constants.%.bf4 // CHECK:STDOUT: %Z.facet.loc12_32.2 => constants.%Z.facet.892 // CHECK:STDOUT: %CC.loc12_32.2 => constants.%CC.4e1 // CHECK:STDOUT: %Z.impl_witness.loc12_39.2 => constants.%Z.impl_witness.40e @@ -1934,8 +1934,8 @@ fn F() { // CHECK:STDOUT: specific @CC.as.Z.impl(constants.%EE) { // CHECK:STDOUT: %E.loc12_14.2 => constants.%EE // CHECK:STDOUT: %DD.loc12_31.2 => constants.%DD.2e1 -// CHECK:STDOUT: %.loc12_32.2 => constants.%.36d // CHECK:STDOUT: %Z.lookup_impl_witness => constants.%Z.impl_witness.8a3 +// CHECK:STDOUT: %.loc12_32.2 => constants.%.36d // CHECK:STDOUT: %Z.facet.loc12_32.2 => constants.%Z.facet.74c // CHECK:STDOUT: %CC.loc12_32.2 => constants.%CC.b19 // CHECK:STDOUT: %Z.impl_witness.loc12_39.2 => constants.%Z.impl_witness.cb4 diff --git a/toolchain/check/testdata/function/generic/indirect_generic_type.carbon b/toolchain/check/testdata/function/generic/indirect_generic_type.carbon index 543815a48a9e..e26fad16ff85 100644 --- a/toolchain/check/testdata/function/generic/indirect_generic_type.carbon +++ b/toolchain/check/testdata/function/generic/indirect_generic_type.carbon @@ -30,8 +30,8 @@ fn F(T:! type, p: T**) -> T* { // CHECK:STDOUT: %.cb6: Core.Form = init_form %ptr.e8f [symbolic] // CHECK:STDOUT: %pattern_type.4f4: type = pattern_type %ptr.e8f [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet [symbolic] @@ -44,8 +44,8 @@ fn F(T:! type, p: T**) -> T* { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc6_10.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc4_20.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc6_10.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc4_20.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc6_10.4: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc6_10.4 (constants.%.299)] diff --git a/toolchain/check/testdata/function/generic/resolve_used.carbon b/toolchain/check/testdata/function/generic/resolve_used.carbon index 7a2740721bd1..bd3daf8aa08d 100644 --- a/toolchain/check/testdata/function/generic/resolve_used.carbon +++ b/toolchain/check/testdata/function/generic/resolve_used.carbon @@ -59,8 +59,8 @@ fn CallNegative() { // CHECK:STDOUT: %T.67d: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %T.as.DefaultOrUnformed.impl.Op.type.6c6: type = fn_type @T.as.DefaultOrUnformed.impl.Op, @T.as.DefaultOrUnformed.impl(%T.67d) [symbolic] // CHECK:STDOUT: %T.as.DefaultOrUnformed.impl.Op.ae1: %T.as.DefaultOrUnformed.impl.Op.type.6c6 = struct_value () [symbolic] -// CHECK:STDOUT: %.4a9: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%Int) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %Int, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.4a9: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%Int) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet.c82: %DefaultOrUnformed.type = facet_value %Int, (%DefaultOrUnformed.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.814: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.c82) [symbolic] // CHECK:STDOUT: %.ca4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.814, %DefaultOrUnformed.facet.c82 [symbolic] @@ -142,8 +142,8 @@ fn CallNegative() { // CHECK:STDOUT: %Int.loc9_27.2: type = class_type @Int, @Int(%N.loc4_19.1) [symbolic = %Int.loc9_27.2 (constants.%Int)] // CHECK:STDOUT: %require_complete: = require_complete_type %Int.loc9_27.2 [symbolic = %require_complete (constants.%require_complete.901)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Int.loc9_27.2 [symbolic = %pattern_type (constants.%pattern_type.764)] -// CHECK:STDOUT: %.loc9_28.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%Int.loc9_27.2) [symbolic = %.loc9_28.3 (constants.%.4a9)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %Int.loc9_27.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness (constants.%DefaultOrUnformed.lookup_impl_witness)] +// CHECK:STDOUT: %.loc9_28.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%Int.loc9_27.2) [symbolic = %.loc9_28.3 (constants.%.4a9)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc9_28.2: %DefaultOrUnformed.type = facet_value %Int.loc9_27.2, (%DefaultOrUnformed.lookup_impl_witness) [symbolic = %DefaultOrUnformed.facet.loc9_28.2 (constants.%DefaultOrUnformed.facet.c82)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc9_28.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type (constants.%DefaultOrUnformed.WithSelf.Op.type.814)] // CHECK:STDOUT: %.loc9_28.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type, %DefaultOrUnformed.facet.loc9_28.2 [symbolic = %.loc9_28.4 (constants.%.ca4)] @@ -209,8 +209,8 @@ fn CallNegative() { // CHECK:STDOUT: %Int.loc9_27.2 => constants.%i0 // CHECK:STDOUT: %require_complete => // CHECK:STDOUT: %pattern_type => constants.%pattern_type.47b -// CHECK:STDOUT: %.loc9_28.3 => constants.%.d6a // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness => constants.%DefaultOrUnformed.impl_witness.879 +// CHECK:STDOUT: %.loc9_28.3 => constants.%.d6a // CHECK:STDOUT: %DefaultOrUnformed.facet.loc9_28.2 => constants.%DefaultOrUnformed.facet.255 // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type => constants.%DefaultOrUnformed.WithSelf.Op.type.bd6 // CHECK:STDOUT: %.loc9_28.4 => constants.%.639 diff --git a/toolchain/check/testdata/function/generic/type_param.carbon b/toolchain/check/testdata/function/generic/type_param.carbon index 3400e2245a29..f0455de4219d 100644 --- a/toolchain/check/testdata/function/generic/type_param.carbon +++ b/toolchain/check/testdata/function/generic/type_param.carbon @@ -33,8 +33,8 @@ fn F(T:! type) { // CHECK:STDOUT: %DefaultOrUnformed.type: type = facet_type <@DefaultOrUnformed> [concrete] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T.67d [symbolic] // CHECK:STDOUT: %pattern_type.51d: type = pattern_type %T.67d [symbolic] -// CHECK:STDOUT: %.713: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %ptr, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.713: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet: %DefaultOrUnformed.type = facet_value %ptr, (%DefaultOrUnformed.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.d74: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet) [symbolic] // CHECK:STDOUT: %.425: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.d74, %DefaultOrUnformed.facet [symbolic] @@ -84,8 +84,8 @@ fn F(T:! type) { // CHECK:STDOUT: %ptr.loc16_11.2: type = ptr_type %T.loc15_6.1 [symbolic = %ptr.loc16_11.2 (constants.%ptr)] // CHECK:STDOUT: %require_complete.loc16: = require_complete_type %ptr.loc16_11.2 [symbolic = %require_complete.loc16 (constants.%require_complete.ef1)] // CHECK:STDOUT: %pattern_type.loc16: type = pattern_type %ptr.loc16_11.2 [symbolic = %pattern_type.loc16 (constants.%pattern_type.4f4)] -// CHECK:STDOUT: %.loc16_12.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr.loc16_11.2) [symbolic = %.loc16_12.3 (constants.%.713)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %ptr.loc16_11.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness (constants.%DefaultOrUnformed.lookup_impl_witness)] +// CHECK:STDOUT: %.loc16_12.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr.loc16_11.2) [symbolic = %.loc16_12.3 (constants.%.713)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc16_12.2: %DefaultOrUnformed.type = facet_value %ptr.loc16_11.2, (%DefaultOrUnformed.lookup_impl_witness) [symbolic = %DefaultOrUnformed.facet.loc16_12.2 (constants.%DefaultOrUnformed.facet)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc16_12.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type (constants.%DefaultOrUnformed.WithSelf.Op.type.d74)] // CHECK:STDOUT: %.loc16_12.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type, %DefaultOrUnformed.facet.loc16_12.2 [symbolic = %.loc16_12.4 (constants.%.425)] diff --git a/toolchain/check/testdata/function/generic/type_param_scope.carbon b/toolchain/check/testdata/function/generic/type_param_scope.carbon index 6f44208a8d83..8cdd8925359c 100644 --- a/toolchain/check/testdata/function/generic/type_param_scope.carbon +++ b/toolchain/check/testdata/function/generic/type_param_scope.carbon @@ -29,8 +29,8 @@ fn F(T:! type, n: T*) -> T* { // CHECK:STDOUT: %pattern_type.4f4: type = pattern_type %ptr [symbolic] // CHECK:STDOUT: %.cb6: Core.Form = init_form %ptr [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet [symbolic] @@ -43,8 +43,8 @@ fn F(T:! type, n: T*) -> T* { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc7_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc7_10.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc4_20.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc7_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc7_10.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc4_20.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc7_10.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc7_10.2 (constants.%.299)] diff --git a/toolchain/check/testdata/generic/dot_self_symbolic_type.carbon b/toolchain/check/testdata/generic/dot_self_symbolic_type.carbon index e157fb568db0..c63d8893ab6a 100644 --- a/toolchain/check/testdata/generic/dot_self_symbolic_type.carbon +++ b/toolchain/check/testdata/generic/dot_self_symbolic_type.carbon @@ -111,6 +111,7 @@ fn H(T:! type) { // CHECK:STDOUT: %.Self.660472.2: %A.type.ade3d9.3 = symbolic_binding .Self [symbolic] // CHECK:STDOUT: %A.lookup_impl_witness.04abbb.2: = lookup_impl_witness %.Self.660472.2, @A, @A(%DD) [symbolic] // CHECK:STDOUT: %impl.elem0.f51d29.2: type = impl_witness_access %A.lookup_impl_witness.04abbb.2, element0 [symbolic] +// CHECK:STDOUT: %A.lookup_impl_witness.780: = lookup_impl_witness %T.091, @A, @A(%DD) [symbolic] // CHECK:STDOUT: %T.67d: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %D.G.type.235: type = fn_type @D.G, @D(%empty_struct_type) [concrete] // CHECK:STDOUT: %D.G.be1: %D.G.type.235 = struct_value () [concrete] @@ -121,6 +122,7 @@ fn H(T:! type) { // CHECK:STDOUT: %.Self.f50: %A.type.69e = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %A.lookup_impl_witness.219: = lookup_impl_witness %.Self.f50, @A, @A(%empty_struct_type) [symbolic_self] // CHECK:STDOUT: %impl.elem0.d97: type = impl_witness_access %A.lookup_impl_witness.219, element0 [symbolic_self] +// CHECK:STDOUT: %A.lookup_impl_witness.c4c: = lookup_impl_witness %T.67d, @A, @A(%empty_struct_type) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%CC.loc6_9.2: type) { @@ -216,8 +218,9 @@ fn H(T:! type) { // CHECK:STDOUT: %C.F: @D.G.%C.F.type (%C.F.type.1f899e.2) = struct_value () [symbolic = %C.F (constants.%C.F.faeec9.2)] // CHECK:STDOUT: %A.type: type = facet_type <@A, @A(%DD)> [symbolic = %A.type (constants.%A.type.ade3d9.3)] // CHECK:STDOUT: %.Self.loc11: @D.G.%A.type (%A.type.ade3d9.3) = symbolic_binding .Self [symbolic = %.Self.loc11 (constants.%.Self.660472.2)] -// CHECK:STDOUT: %A.lookup_impl_witness: = lookup_impl_witness %.Self.loc11, @A, @A(%DD) [symbolic = %A.lookup_impl_witness (constants.%A.lookup_impl_witness.04abbb.2)] -// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %A.lookup_impl_witness, element0 [symbolic = %impl.elem0 (constants.%impl.elem0.f51d29.2)] +// CHECK:STDOUT: %A.lookup_impl_witness.loc11: = lookup_impl_witness %.Self.loc11, @A, @A(%DD) [symbolic = %A.lookup_impl_witness.loc11 (constants.%A.lookup_impl_witness.04abbb.2)] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %A.lookup_impl_witness.loc11, element0 [symbolic = %impl.elem0 (constants.%impl.elem0.f51d29.2)] +// CHECK:STDOUT: %A.lookup_impl_witness.loc25: = lookup_impl_witness %T.loc16_8.1, @A, @A(%DD) [symbolic = %A.lookup_impl_witness.loc25 (constants.%A.lookup_impl_witness.780)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: @@ -293,8 +296,9 @@ fn H(T:! type) { // CHECK:STDOUT: %C.F => constants.%C.F.240 // CHECK:STDOUT: %A.type => constants.%A.type.69e // CHECK:STDOUT: %.Self.loc11 => constants.%.Self.f50 -// CHECK:STDOUT: %A.lookup_impl_witness => constants.%A.lookup_impl_witness.219 +// CHECK:STDOUT: %A.lookup_impl_witness.loc11 => constants.%A.lookup_impl_witness.219 // CHECK:STDOUT: %impl.elem0 => constants.%impl.elem0.d97 +// CHECK:STDOUT: %A.lookup_impl_witness.loc25 => constants.%A.lookup_impl_witness.c4c // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%empty_struct_type) { @@ -340,16 +344,16 @@ fn H(T:! type) { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %ptr.e8f8f9.2: type = ptr_type %DD [symbolic] // CHECK:STDOUT: %B.type.abcc5d.2: type = facet_type <@B, @B(%ptr.e8f8f9.2)> [symbolic] -// CHECK:STDOUT: %.77d: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.e8f8f9.2, %T.091) [symbolic] // CHECK:STDOUT: %B.lookup_impl_witness.52c: = lookup_impl_witness %T.091, @B, @B(%ptr.e8f8f9.2) [symbolic] +// CHECK:STDOUT: %.77d: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.e8f8f9.2, %T.091) [symbolic] // CHECK:STDOUT: %B.facet.b5c: %B.type.abcc5d.2 = facet_value %T.091, (%B.lookup_impl_witness.52c) [symbolic] // CHECK:STDOUT: %T.67d: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %D.G.type.235: type = fn_type @D.G, @D(%empty_struct_type) [concrete] // CHECK:STDOUT: %D.G.be1: %D.G.type.235 = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %B.type.a69: type = facet_type <@B, @B(%ptr.c28)> [concrete] -// CHECK:STDOUT: %.5ef: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.c28, %T.67d) [symbolic] // CHECK:STDOUT: %B.lookup_impl_witness.eb0: = lookup_impl_witness %T.67d, @B, @B(%ptr.c28) [symbolic] +// CHECK:STDOUT: %.5ef: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.c28, %T.67d) [symbolic] // CHECK:STDOUT: %B.facet.4b0: %B.type.a69 = facet_value %T.67d, (%B.lookup_impl_witness.eb0) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -448,8 +452,8 @@ fn H(T:! type) { // CHECK:STDOUT: %DD: type = symbolic_binding DD, 0 [symbolic = %DD (constants.%DD)] // CHECK:STDOUT: %ptr.loc21_14.2: type = ptr_type %DD [symbolic = %ptr.loc21_14.2 (constants.%ptr.e8f8f9.2)] // CHECK:STDOUT: %B.type.loc21_15.2: type = facet_type <@B, @B(%ptr.loc21_14.2)> [symbolic = %B.type.loc21_15.2 (constants.%B.type.abcc5d.2)] -// CHECK:STDOUT: %.loc21_7.2: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.loc21_14.2, %T.loc15_8.1) [symbolic = %.loc21_7.2 (constants.%.77d)] // CHECK:STDOUT: %B.lookup_impl_witness: = lookup_impl_witness %T.loc15_8.1, @B, @B(%ptr.loc21_14.2) [symbolic = %B.lookup_impl_witness (constants.%B.lookup_impl_witness.52c)] +// CHECK:STDOUT: %.loc21_7.2: require_specific_def_type = require_specific_def @BB.as.B.impl(%ptr.loc21_14.2, %T.loc15_8.1) [symbolic = %.loc21_7.2 (constants.%.77d)] // CHECK:STDOUT: %B.facet.loc21_7.2: @D.G.%B.type.loc21_15.2 (%B.type.abcc5d.2) = facet_value %T.loc15_8.1, (%B.lookup_impl_witness) [symbolic = %B.facet.loc21_7.2 (constants.%B.facet.b5c)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { @@ -511,8 +515,8 @@ fn H(T:! type) { // CHECK:STDOUT: %DD => constants.%empty_struct_type // CHECK:STDOUT: %ptr.loc21_14.2 => constants.%ptr.c28 // CHECK:STDOUT: %B.type.loc21_15.2 => constants.%B.type.a69 -// CHECK:STDOUT: %.loc21_7.2 => constants.%.5ef // CHECK:STDOUT: %B.lookup_impl_witness => constants.%B.lookup_impl_witness.eb0 +// CHECK:STDOUT: %.loc21_7.2 => constants.%.5ef // CHECK:STDOUT: %B.facet.loc21_7.2 => constants.%B.facet.4b0 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/template/unimplemented.carbon b/toolchain/check/testdata/generic/template/unimplemented.carbon index 18b173152171..6bdaae55c285 100644 --- a/toolchain/check/testdata/generic/template/unimplemented.carbon +++ b/toolchain/check/testdata/generic/template/unimplemented.carbon @@ -90,6 +90,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %MulWith.type.8b4: type = generic_interface_type @MulWith [concrete] // CHECK:STDOUT: %MulWith.generic: %MulWith.type.8b4 = struct_value () [concrete] +// CHECK:STDOUT: %MulWith.lookup_impl_witness.052: = lookup_impl_witness @F.%.loc11_11.5, @MulWith, @MulWith(Core.IntLiteral) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -140,6 +141,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: %.loc11_11.3: = refine_type_action %x.ref, %T.loc6_15.1 [template] // CHECK:STDOUT: %.loc11_11.4: = access_member_action %.loc11_11.1, n [template] // CHECK:STDOUT: %.loc11_11.5: type = type_of_inst %.loc11_11.4 [template] +// CHECK:STDOUT: %MulWith.lookup_impl_witness: = lookup_impl_witness %.loc11_11.5, @MulWith, @MulWith(Core.IntLiteral) [template = %MulWith.lookup_impl_witness (constants.%MulWith.lookup_impl_witness.052)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%x.param: @F.%T.loc6_15.1 (%T)) -> out %return.param: %i32 { // CHECK:STDOUT: !entry: @@ -178,6 +180,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %MulWith.type.8b4: type = generic_interface_type @MulWith [concrete] // CHECK:STDOUT: %MulWith.generic: %MulWith.type.8b4 = struct_value () [concrete] +// CHECK:STDOUT: %MulWith.lookup_impl_witness.292: = lookup_impl_witness @F.%.loc16_11.3, @MulWith, @MulWith(Core.IntLiteral) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -233,6 +236,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %.loc16_11.2: = access_member_action %c.ref, n [template] // CHECK:STDOUT: %.loc16_11.3: type = type_of_inst %.loc16_11.2 [template] +// CHECK:STDOUT: %MulWith.lookup_impl_witness: = lookup_impl_witness %.loc16_11.3, @MulWith, @MulWith(Core.IntLiteral) [template = %MulWith.lookup_impl_witness (constants.%MulWith.lookup_impl_witness.292)] // CHECK:STDOUT: // CHECK:STDOUT: fn() -> out %return.param: %i32 { // CHECK:STDOUT: !entry: @@ -270,6 +274,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness.6d3: = lookup_impl_witness %T.765, @ImplicitAs, @ImplicitAs(%i32) [template] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %T.765, @Destroy [template] @@ -329,6 +334,7 @@ fn F[template T:! Core.Destroy](x: T) { // CHECK:STDOUT: %ImplicitAs.type.loc14_3.2: type = facet_type <@ImplicitAs, @ImplicitAs(%T.binding.as_type)> [template = %ImplicitAs.type.loc14_3.2 (constants.%ImplicitAs.type.112)] // CHECK:STDOUT: %.loc14_3.3: = access_member_action %ImplicitAs.type.loc14_3.1, Convert [template] // CHECK:STDOUT: %.loc14_3.4: type = type_of_inst %.loc14_3.3 [template] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %T.loc4_15.1, @ImplicitAs, @ImplicitAs(constants.%i32) [template = %ImplicitAs.lookup_impl_witness (constants.%ImplicitAs.lookup_impl_witness.6d3)] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %T.loc4_15.1, @Destroy [template = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] // CHECK:STDOUT: %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%T.loc4_15.1) [template = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.cb2e47.2)] // CHECK:STDOUT: %.loc14_3.5: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %T.loc4_15.1 [template = %.loc14_3.5 (constants.%.d5f)] diff --git a/toolchain/check/testdata/generic/template_dependence.carbon b/toolchain/check/testdata/generic/template_dependence.carbon index aad74991fdae..264b9ea4038b 100644 --- a/toolchain/check/testdata/generic/template_dependence.carbon +++ b/toolchain/check/testdata/generic/template_dependence.carbon @@ -45,8 +45,8 @@ fn F(template T:! type, U:! type) -> (T, U) { // CHECK:STDOUT: %require_complete.fbe: = require_complete_type %ptr.125 [template] // CHECK:STDOUT: %require_complete.ef162c.1: = require_complete_type %ptr.e8f8f9.1 [template] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67db0b.1) [template] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f8f9.1, @Copy [template] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67db0b.1) [template] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e8f8f9.1, (%Copy.lookup_impl_witness.2e6) [template] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [template] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet [template] @@ -93,8 +93,8 @@ fn F(template T:! type, U:! type) -> (T, U) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc5_26: = require_complete_type %ptr.loc5_30.1 [template = %require_complete.loc5_26 (constants.%require_complete.fbe)] // CHECK:STDOUT: %require_complete.loc5_37: = require_complete_type %ptr.loc5_29.1 [template = %require_complete.loc5_37 (constants.%require_complete.ef162c.1)] -// CHECK:STDOUT: %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_15.1) [template = %.loc6_10.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc5_29.1, @Copy [template = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_15.1) [template = %.loc6_10.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc5_29.1, (%Copy.lookup_impl_witness) [template = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [template = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc6_10.4: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [template = %.loc6_10.4 (constants.%.299)] diff --git a/toolchain/check/testdata/impl/error_recovery.carbon b/toolchain/check/testdata/impl/error_recovery.carbon index 982de24e9425..bfc925b520e1 100644 --- a/toolchain/check/testdata/impl/error_recovery.carbon +++ b/toolchain/check/testdata/impl/error_recovery.carbon @@ -164,8 +164,8 @@ impl C as I { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %.242: require_specific_def_type = require_specific_def @T.as.Z.impl(%T) [symbolic] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %T, @Z [symbolic] +// CHECK:STDOUT: %.242: require_specific_def_type = require_specific_def @T.as.Z.impl(%T) [symbolic] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %T, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%Z.facet) [symbolic] // CHECK:STDOUT: } @@ -186,8 +186,8 @@ impl C as I { // CHECK:STDOUT: %T.loc13_6.1: type = symbolic_binding T, 0 [symbolic = %T.loc13_6.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc19_6.2: require_specific_def_type = require_specific_def @T.as.Z.impl(%T.loc13_6.1) [symbolic = %.loc19_6.2 (constants.%.242)] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %T.loc13_6.1, @Z [symbolic = %Z.lookup_impl_witness (constants.%Z.lookup_impl_witness)] +// CHECK:STDOUT: %.loc19_6.2: require_specific_def_type = require_specific_def @T.as.Z.impl(%T.loc13_6.1) [symbolic = %.loc19_6.2 (constants.%.242)] // CHECK:STDOUT: %Z.facet.loc19_6.2: %Z.type = facet_value %T.loc13_6.1, (%Z.lookup_impl_witness) [symbolic = %Z.facet.loc19_6.2 (constants.%Z.facet)] // CHECK:STDOUT: %F.specific_fn.loc19_3.2: = specific_function constants.%F, @F(%Z.facet.loc19_6.2) [symbolic = %F.specific_fn.loc19_3.2 (constants.%F.specific_fn)] // CHECK:STDOUT: @@ -218,8 +218,8 @@ impl C as I { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %.242: require_specific_def_type = require_specific_def @T.as.Z.impl(%T) [symbolic] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %T, @Z [symbolic] +// CHECK:STDOUT: %.242: require_specific_def_type = require_specific_def @T.as.Z.impl(%T) [symbolic] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %T, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%Z.facet) [symbolic] // CHECK:STDOUT: %.194: require_specific_def_type = require_specific_def @T.as.Z.impl(%empty_tuple.type) [concrete] @@ -241,8 +241,8 @@ impl C as I { // CHECK:STDOUT: %T.loc13_6.1: type = symbolic_binding T, 0 [symbolic = %T.loc13_6.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc19_6.2: require_specific_def_type = require_specific_def @T.as.Z.impl(%T.loc13_6.1) [symbolic = %.loc19_6.2 (constants.%.242)] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %T.loc13_6.1, @Z [symbolic = %Z.lookup_impl_witness (constants.%Z.lookup_impl_witness)] +// CHECK:STDOUT: %.loc19_6.2: require_specific_def_type = require_specific_def @T.as.Z.impl(%T.loc13_6.1) [symbolic = %.loc19_6.2 (constants.%.242)] // CHECK:STDOUT: %Z.facet.loc19_6.2: %Z.type = facet_value %T.loc13_6.1, (%Z.lookup_impl_witness) [symbolic = %Z.facet.loc19_6.2 (constants.%Z.facet)] // CHECK:STDOUT: %F.specific_fn.loc19_3.2: = specific_function constants.%F, @F(%Z.facet.loc19_6.2) [symbolic = %F.specific_fn.loc19_3.2 (constants.%F.specific_fn)] // CHECK:STDOUT: @@ -266,8 +266,8 @@ impl C as I { // CHECK:STDOUT: %T.loc13_6.1 => constants.%empty_tuple.type // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %.loc19_6.2 => constants.%.194 // CHECK:STDOUT: %Z.lookup_impl_witness => +// CHECK:STDOUT: %.loc19_6.2 => constants.%.194 // CHECK:STDOUT: %Z.facet.loc19_6.2 => // CHECK:STDOUT: %F.specific_fn.loc19_3.2 => // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/impl_thunk.carbon b/toolchain/check/testdata/impl/impl_thunk.carbon index 005b1dbf0dde..335a34c70b38 100644 --- a/toolchain/check/testdata/impl/impl_thunk.carbon +++ b/toolchain/check/testdata/impl/impl_thunk.carbon @@ -837,8 +837,8 @@ impl () as I({}) { // CHECK:STDOUT: %.023143.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type.735e75.3, %U.035 [symbolic] // CHECK:STDOUT: %impl.elem0.594c59.2: %.023143.2 = impl_witness_access %Copy.lookup_impl_witness.58dce0.2, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn.bdce5c.2: = specific_impl_function %impl.elem0.594c59.2, @Copy.WithSelf.Op(%U.035) [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %empty_tuple.type.as.I.impl.F.specific_fn: = specific_function %empty_tuple.type.as.I.impl.F.8be29b.1, @empty_tuple.type.as.I.impl.F.loc10_34.1(%Copy.facet) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] @@ -929,8 +929,8 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc10_34.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_8.1) [symbolic = %.loc10_34.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc10_34.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_8.1) [symbolic = %.loc10_34.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet.loc10_34.2: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc10_34.2 (constants.%Copy.facet)] // CHECK:STDOUT: %empty_tuple.type.as.I.impl.F.specific_fn.loc10_34.2: = specific_function constants.%empty_tuple.type.as.I.impl.F.8be29b.1, @empty_tuple.type.as.I.impl.F.loc10_34.1(%Copy.facet.loc10_34.2) [symbolic = %empty_tuple.type.as.I.impl.F.specific_fn.loc10_34.2 (constants.%empty_tuple.type.as.I.impl.F.specific_fn)] // CHECK:STDOUT: @@ -1002,8 +1002,8 @@ impl () as I({}) { // CHECK:STDOUT: %.023143.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type.735e75.3, %U.035 [symbolic] // CHECK:STDOUT: %impl.elem0.594c59.2: %.023143.2 = impl_witness_access %Copy.lookup_impl_witness.58dce0.2, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn.bdce5c.2: = specific_impl_function %impl.elem0.594c59.2, @Copy.WithSelf.Op(%U.035) [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %empty_tuple.type.as.I.impl.F.specific_fn: = specific_function %empty_tuple.type.as.I.impl.F.8be29b.1, @empty_tuple.type.as.I.impl.F.loc10_51.1(%Copy.facet) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] @@ -1102,8 +1102,8 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: %.loc10_51.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_20.1) [symbolic = %.loc10_51.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc10_51.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc5_20.1) [symbolic = %.loc10_51.2 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet.loc10_51.2: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc10_51.2 (constants.%Copy.facet)] // CHECK:STDOUT: %empty_tuple.type.as.I.impl.F.specific_fn.loc10_51.2: = specific_function constants.%empty_tuple.type.as.I.impl.F.8be29b.1, @empty_tuple.type.as.I.impl.F.loc10_51.1(%Copy.facet.loc10_51.2) [symbolic = %empty_tuple.type.as.I.impl.F.specific_fn.loc10_51.2 (constants.%empty_tuple.type.as.I.impl.F.specific_fn)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/import_builtin_call.carbon b/toolchain/check/testdata/impl/import_builtin_call.carbon index 66d72d8320b1..2e07fadbd3a2 100644 --- a/toolchain/check/testdata/impl/import_builtin_call.carbon +++ b/toolchain/check/testdata/impl/import_builtin_call.carbon @@ -113,8 +113,8 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt); // CHECK:STDOUT: %Add.WithSelf.Op.935: %Add.WithSelf.Op.type.6d2 = struct_value () [symbolic] // CHECK:STDOUT: %Double.type: type = fn_type @Double [concrete] // CHECK:STDOUT: %Double: %Double.type = struct_value () [concrete] -// CHECK:STDOUT: %.c60: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N) [symbolic] // CHECK:STDOUT: %Add.lookup_impl_witness: = lookup_impl_witness %MyInt, @Add [symbolic] +// CHECK:STDOUT: %.c60: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N) [symbolic] // CHECK:STDOUT: %Add.facet.9ab: %Add.type = facet_value %MyInt, (%Add.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Add.WithSelf.Op.type.3e8: type = fn_type @Add.WithSelf.Op, @Add.WithSelf(%Add.facet.9ab) [symbolic] // CHECK:STDOUT: %Add.WithSelf.Op.451: %Add.WithSelf.Op.type.3e8 = struct_value () [symbolic] @@ -359,8 +359,8 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt); // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %MyInt.loc19_39.1 [symbolic = %require_complete (constants.%require_complete.9fa)] -// CHECK:STDOUT: %.loc20_11.1: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N.loc19_11.1) [symbolic = %.loc20_11.1 (constants.%.c60)] // CHECK:STDOUT: %Add.lookup_impl_witness: = lookup_impl_witness %MyInt.loc19_39.1, @Add [symbolic = %Add.lookup_impl_witness (constants.%Add.lookup_impl_witness)] +// CHECK:STDOUT: %.loc20_11.1: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N.loc19_11.1) [symbolic = %.loc20_11.1 (constants.%.c60)] // CHECK:STDOUT: %Add.facet.loc20_11: %Add.type = facet_value %MyInt.loc19_39.1, (%Add.lookup_impl_witness) [symbolic = %Add.facet.loc20_11 (constants.%Add.facet.9ab)] // CHECK:STDOUT: %Add.WithSelf.Op.type: type = fn_type @Add.WithSelf.Op, @Add.WithSelf(%Add.facet.loc20_11) [symbolic = %Add.WithSelf.Op.type (constants.%Add.WithSelf.Op.type.3e8)] // CHECK:STDOUT: %.loc20_11.2: type = fn_type_with_self_type %Add.WithSelf.Op.type, %Add.facet.loc20_11 [symbolic = %.loc20_11.2 (constants.%.d02)] @@ -625,8 +625,8 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt); // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %MyInt [symbolic = %require_complete (constants.%require_complete.9fa)] -// CHECK:STDOUT: %.2: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N) [symbolic = %.2 (constants.%.c60)] // CHECK:STDOUT: %Add.lookup_impl_witness: = lookup_impl_witness %MyInt, @Add [symbolic = %Add.lookup_impl_witness (constants.%Add.lookup_impl_witness)] +// CHECK:STDOUT: %.2: require_specific_def_type = require_specific_def @MyInt.as.Add.impl(%N) [symbolic = %.2 (constants.%.c60)] // CHECK:STDOUT: %Add.facet: %Add.type = facet_value %MyInt, (%Add.lookup_impl_witness) [symbolic = %Add.facet (constants.%Add.facet.9ab)] // CHECK:STDOUT: %Add.WithSelf.Op.type: type = fn_type @Add.WithSelf.Op, @Add.WithSelf(%Add.facet) [symbolic = %Add.WithSelf.Op.type (constants.%Add.WithSelf.Op.type.3e8)] // CHECK:STDOUT: %.3: type = fn_type_with_self_type %Add.WithSelf.Op.type, %Add.facet [symbolic = %.3 (constants.%.d02)] @@ -735,8 +735,8 @@ var n: Int(64) = MakeFromClass(FromLiteral(64) as OtherInt); // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type.4a1 -// CHECK:STDOUT: %.2 => constants.%.3de // CHECK:STDOUT: %Add.lookup_impl_witness => constants.%Add.impl_witness.868 +// CHECK:STDOUT: %.2 => constants.%.3de // CHECK:STDOUT: %Add.facet => constants.%Add.facet.1f9 // CHECK:STDOUT: %Add.WithSelf.Op.type => constants.%Add.WithSelf.Op.type.626 // CHECK:STDOUT: %.3 => constants.%.166 diff --git a/toolchain/check/testdata/impl/import_generic.carbon b/toolchain/check/testdata/impl/import_generic.carbon index a51d164090b4..647d11c98590 100644 --- a/toolchain/check/testdata/impl/import_generic.carbon +++ b/toolchain/check/testdata/impl/import_generic.carbon @@ -684,13 +684,13 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f642.1 [symbolic] // CHECK:STDOUT: %empty_struct.a40: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %J.type.d682d6.2: type = facet_type <@J, @J(%empty_struct_type)> [concrete] -// CHECK:STDOUT: %Self.e1f642.2: %J.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete] // CHECK:STDOUT: %I.type.ab5: type = facet_type <@I, @I(%empty_struct_type)> [concrete] // CHECK:STDOUT: %Self.025: %I.type.ab5 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %complete_type.5b1: = complete_type_witness %I.type.ab5 [concrete] -// CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Self.e1f642.2: %J.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %I.facet: %I.type.ab5 = facet_value %C, (%I.impl_witness) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -819,7 +819,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Self => constants.%Self.e1f642.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%Self.e1f642.1) { +// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%C.type.facet) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %T => constants.%empty_struct_type // CHECK:STDOUT: %I.type => constants.%I.type.ab5 @@ -838,13 +838,6 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%C.type.facet) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%empty_struct_type -// CHECK:STDOUT: %I.type => constants.%I.type.ab5 -// CHECK:STDOUT: %require_complete => constants.%complete_type.5b1 -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @J.WithSelf.Self.binding.as_type.impls.I.type.require(constants.%empty_struct_type, constants.%C.type.facet) { // CHECK:STDOUT: %T => constants.%empty_struct_type // CHECK:STDOUT: %J.type => constants.%J.type.d682d6.2 @@ -853,6 +846,13 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %I.type => constants.%I.type.ab5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%Self.e1f642.1) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: %I.type => constants.%I.type.ab5 +// CHECK:STDOUT: %require_complete => constants.%complete_type.5b1 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.WithSelf(constants.%empty_struct_type, constants.%I.facet) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } @@ -1144,11 +1144,10 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %N.type.b47: type = generic_named_constaint_type @N [concrete] // CHECK:STDOUT: %empty_struct: %N.type.b47 = struct_value () [concrete] // CHECK:STDOUT: %N.type.d682d6.1: type = facet_type <@N, @N(%T)> [symbolic] -// CHECK:STDOUT: %Self.e1f642.1: %N.type.d682d6.1 = symbolic_binding Self, 1 [symbolic] -// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f642.1 [symbolic] +// CHECK:STDOUT: %Self.e1f: %N.type.d682d6.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f [symbolic] // CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete] // CHECK:STDOUT: %N.type.d682d6.2: type = facet_type <@N, @N(%ptr)> [symbolic] -// CHECK:STDOUT: %Self.e1f642.2: %N.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -1173,7 +1172,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Main.import_ref.213: type = import_ref Main//import_generic, loc15_18, loaded [symbolic = @N.WithSelf.Self.binding.as_type.impls.I.type.require.%Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %Main.import_ref.3582b1.2: type = import_ref Main//import_generic, loc15_27, loaded [symbolic = @N.WithSelf.Self.binding.as_type.impls.I.type.require.%I.type (constants.%I.type.1ab)] // CHECK:STDOUT: %Main.import_ref.b3bc94.6: type = import_ref Main//import_generic, loc14_14, loaded [symbolic = @N.%T (constants.%T)] -// CHECK:STDOUT: %Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1) = import_ref Main//import_generic, loc14_24, loaded [symbolic = @N.%Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1) = import_ref Main//import_generic, loc14_24, loaded [symbolic = @N.%Self (constants.%Self.e1f)] // CHECK:STDOUT: %Main.import_ref.830 = import_ref Main//import_generic, loc14_24, unloaded // CHECK:STDOUT: %Main.import_ref.b3bc94.7: type = import_ref Main//import_generic, loc14_14, loaded [symbolic = @N.%T (constants.%T)] // CHECK:STDOUT: } @@ -1290,7 +1289,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.d682d6.1)] -// CHECK:STDOUT: %Self: @N.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Self: @N.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: !members: @@ -1307,7 +1306,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: generic require @N.WithSelf.Self.binding.as_type.impls.I.type.require(imports.%Main.import_ref.b3bc94.6: type, imports.%Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1)) [from "import_generic.carbon"] { // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.d682d6.1)] -// CHECK:STDOUT: %Self: @N.WithSelf.Self.binding.as_type.impls.I.type.require.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Self: @N.WithSelf.Self.binding.as_type.impls.I.type.require.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.1ab)] // CHECK:STDOUT: } @@ -1460,23 +1459,14 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%T) { // CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %N.type => constants.%N.type.d682d6.1 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%T, constants.%Self.e1f642.1) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: %I.type => constants.%I.type.1ab -// CHECK:STDOUT: %require_complete => constants.%require_complete.e36 -// CHECK:STDOUT: } +// CHECK:STDOUT: specific @N.WithSelf(constants.%T, constants.%Self.e1f) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf.Self.binding.as_type.impls.I.type.require(constants.%T, constants.%Self.e1f642.1) { +// CHECK:STDOUT: specific @N.WithSelf.Self.binding.as_type.impls.I.type.require(constants.%T, constants.%Self.e1f) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %N.type => constants.%N.type.d682d6.1 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.1 +// CHECK:STDOUT: %Self => constants.%Self.e1f // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: %I.type => constants.%I.type.1ab // CHECK:STDOUT: } @@ -1503,17 +1493,6 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%ptr) { // CHECK:STDOUT: %T => constants.%ptr -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %N.type => constants.%N.type.d682d6.2 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.2 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr, constants.%Self.e1f642.1) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%ptr -// CHECK:STDOUT: %I.type => constants.%I.type.e19 -// CHECK:STDOUT: %require_complete => constants.%require_complete.ffd // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @N.WithSelf(constants.%ptr, constants.%C.type.facet) { @@ -1755,11 +1734,11 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f642.1 [symbolic] // CHECK:STDOUT: %ptr.125: type = ptr_type %ptr.e8f [symbolic] // CHECK:STDOUT: %N.type.d682d6.2: type = facet_type <@N, @N(%ptr.125)> [symbolic] -// CHECK:STDOUT: %Self.e1f642.2: %N.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete] // CHECK:STDOUT: %I.type.08a: type = facet_type <@I, @I(%ptr.125)> [symbolic] // CHECK:STDOUT: %require_complete.ea6: = require_complete_type %I.type.08a [symbolic] -// CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete] // CHECK:STDOUT: %I.impl_witness.d57: = impl_witness @C.as.I.impl.c93.%I.impl_witness_table, @C.as.I.impl.c93(%T) [symbolic] +// CHECK:STDOUT: %Self.e1f642.2: %N.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %require_complete.533: = require_complete_type %N.type.d682d6.2 [symbolic] // CHECK:STDOUT: %I.facet.3e9: %I.type.08a = facet_value %C, (%I.impl_witness.d57) [symbolic] // CHECK:STDOUT: } @@ -1989,7 +1968,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Self => constants.%Self.e1f642.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr.125, constants.%Self.e1f642.1) { +// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr.125, constants.%C.type.facet) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %T => constants.%ptr.125 // CHECK:STDOUT: %I.type => constants.%I.type.08a @@ -2000,13 +1979,6 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %T => constants.%ptr.125 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr.125, constants.%C.type.facet) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%ptr.125 -// CHECK:STDOUT: %I.type => constants.%I.type.08a -// CHECK:STDOUT: %require_complete => constants.%require_complete.ea6 -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @N.WithSelf.Self.binding.as_type.impls.I.type.require(constants.%ptr.125, constants.%C.type.facet) { // CHECK:STDOUT: %T => constants.%ptr.125 // CHECK:STDOUT: %N.type => constants.%N.type.d682d6.2 @@ -2023,6 +1995,13 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %I.impl_witness.loc6_36.2 => constants.%I.impl_witness.d57 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr.125, constants.%Self.e1f642.1) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T => constants.%ptr.125 +// CHECK:STDOUT: %I.type => constants.%I.type.08a +// CHECK:STDOUT: %require_complete => constants.%require_complete.ea6 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.WithSelf(constants.%ptr.125, constants.%I.facet.3e9) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } @@ -2259,12 +2238,11 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %N.type.b47: type = generic_named_constaint_type @N [concrete] // CHECK:STDOUT: %empty_struct: %N.type.b47 = struct_value () [concrete] // CHECK:STDOUT: %N.type.d682d6.1: type = facet_type <@N, @N(%T)> [symbolic] -// CHECK:STDOUT: %Self.e1f642.1: %N.type.d682d6.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.e1f: %N.type.d682d6.1 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %require_complete.cc6: = require_complete_type %J.type.04e [symbolic] -// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f642.1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.e1f [symbolic] // CHECK:STDOUT: %D.type.facet: %type = facet_value %D, () [concrete] // CHECK:STDOUT: %N.type.d682d6.2: type = facet_type <@N, @N(%ptr)> [symbolic] -// CHECK:STDOUT: %Self.e1f642.2: %N.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %require_complete.19b: = require_complete_type %J.type.80f [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2288,7 +2266,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Main.import_ref.213: type = import_ref Main//import_generic_decl, loc8_18, loaded [symbolic = @N.WithSelf.Self.binding.as_type.impls.J.type.require.%Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %Main.import_ref.f2a55c.2: type = import_ref Main//import_generic_decl, loc8_27, loaded [symbolic = @N.WithSelf.Self.binding.as_type.impls.J.type.require.%J.type (constants.%J.type.04e)] // CHECK:STDOUT: %Main.import_ref.b3bc94.6: type = import_ref Main//import_generic_decl, loc7_14, loaded [symbolic = @N.%T (constants.%T)] -// CHECK:STDOUT: %Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1) = import_ref Main//import_generic_decl, loc7_24, loaded [symbolic = @N.%Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1) = import_ref Main//import_generic_decl, loc7_24, loaded [symbolic = @N.%Self (constants.%Self.e1f)] // CHECK:STDOUT: %Main.import_ref.830 = import_ref Main//import_generic_decl, loc7_24, unloaded // CHECK:STDOUT: %Main.import_ref.b3bc94.7: type = import_ref Main//import_generic_decl, loc7_14, loaded [symbolic = @N.%T (constants.%T)] // CHECK:STDOUT: } @@ -2405,7 +2383,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.d682d6.1)] -// CHECK:STDOUT: %Self: @N.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Self: @N.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: !members: @@ -2422,7 +2400,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: generic require @N.WithSelf.Self.binding.as_type.impls.J.type.require(imports.%Main.import_ref.b3bc94.6: type, imports.%Main.import_ref.2fc394.2: @N.%N.type (%N.type.d682d6.1)) [from "fail_import_generic_decl.carbon"] { // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.d682d6.1)] -// CHECK:STDOUT: %Self: @N.WithSelf.Self.binding.as_type.impls.J.type.require.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f642.1)] +// CHECK:STDOUT: %Self: @N.WithSelf.Self.binding.as_type.impls.J.type.require.%N.type (%N.type.d682d6.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.e1f)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.04e)] // CHECK:STDOUT: } @@ -2569,23 +2547,14 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%T) { // CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %N.type => constants.%N.type.d682d6.1 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.1 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%T, constants.%Self.e1f642.1) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: %J.type => constants.%J.type.04e -// CHECK:STDOUT: %require_complete => constants.%require_complete.cc6 -// CHECK:STDOUT: } +// CHECK:STDOUT: specific @N.WithSelf(constants.%T, constants.%Self.e1f) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf.Self.binding.as_type.impls.J.type.require(constants.%T, constants.%Self.e1f642.1) { +// CHECK:STDOUT: specific @N.WithSelf.Self.binding.as_type.impls.J.type.require(constants.%T, constants.%Self.e1f) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %N.type => constants.%N.type.d682d6.1 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.1 +// CHECK:STDOUT: %Self => constants.%Self.e1f // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: %J.type => constants.%J.type.04e // CHECK:STDOUT: } @@ -2612,17 +2581,6 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%ptr) { // CHECK:STDOUT: %T => constants.%ptr -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %N.type => constants.%N.type.d682d6.2 -// CHECK:STDOUT: %Self => constants.%Self.e1f642.2 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @N.WithSelf(constants.%ptr, constants.%Self.e1f642.1) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %T => constants.%ptr -// CHECK:STDOUT: %J.type => constants.%J.type.80f -// CHECK:STDOUT: %require_complete => constants.%require_complete.19b // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @N.WithSelf(constants.%ptr, constants.%D.type.facet) { diff --git a/toolchain/check/testdata/impl/import_self_specific.carbon b/toolchain/check/testdata/impl/import_self_specific.carbon index e51e4fb11157..b9d756995467 100644 --- a/toolchain/check/testdata/impl/import_self_specific.carbon +++ b/toolchain/check/testdata/impl/import_self_specific.carbon @@ -93,9 +93,9 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %Self.ab9, @I [symbolic] // CHECK:STDOUT: %impl.elem0: %Y.type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic] // CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0 [symbolic] +// CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %impl.elem0, @Z [symbolic] // CHECK:STDOUT: %Z.impl_witness.64d: = impl_witness @U.as.Z.impl.%Z.impl_witness_table, @U.as.Z.impl(%as_type) [symbolic] // CHECK:STDOUT: %.bf4: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic] -// CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %impl.elem0, @Z [symbolic] // CHECK:STDOUT: %Z.facet.05b: %Z.type = facet_value %as_type, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %C.6ff: type = class_type @C, @C(%Z.facet.05b) [symbolic] // CHECK:STDOUT: %pattern_type.850: type = pattern_type %C.6ff [symbolic] @@ -260,8 +260,8 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %Self, @I [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness)] // CHECK:STDOUT: %impl.elem0.loc24_13.1: %Y.type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc24_13.1 (constants.%impl.elem0)] // CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0.loc24_13.1 [symbolic = %as_type (constants.%as_type)] -// CHECK:STDOUT: %.loc24_18.1: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic = %.loc24_18.1 (constants.%.bf4)] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %impl.elem0.loc24_13.1, @Z [symbolic = %Z.lookup_impl_witness (constants.%Z.lookup_impl_witness)] +// CHECK:STDOUT: %.loc24_18.1: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic = %.loc24_18.1 (constants.%.bf4)] // CHECK:STDOUT: %Z.facet.loc24_18.1: %Z.type = facet_value %as_type, (%Z.lookup_impl_witness) [symbolic = %Z.facet.loc24_18.1 (constants.%Z.facet.05b)] // CHECK:STDOUT: %C.loc24_18.1: type = class_type @C, @C(%Z.facet.loc24_18.1) [symbolic = %C.loc24_18.1 (constants.%C.6ff)] // CHECK:STDOUT: %pattern_type: type = pattern_type %C.loc24_18.1 [symbolic = %pattern_type (constants.%pattern_type.850)] @@ -317,8 +317,8 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.lookup_impl_witness // CHECK:STDOUT: %impl.elem0.loc24_13.1 => constants.%impl.elem0 // CHECK:STDOUT: %as_type => constants.%as_type -// CHECK:STDOUT: %.loc24_18.1 => constants.%.bf4 // CHECK:STDOUT: %Z.lookup_impl_witness => constants.%Z.lookup_impl_witness +// CHECK:STDOUT: %.loc24_18.1 => constants.%.bf4 // CHECK:STDOUT: %Z.facet.loc24_18.1 => constants.%Z.facet.05b // CHECK:STDOUT: %C.loc24_18.1 => constants.%C.6ff // CHECK:STDOUT: %pattern_type => constants.%pattern_type.850 @@ -349,8 +349,8 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %Self.d4d: %Y.type = symbolic_binding Self, 0 [symbolic] // CHECK:STDOUT: %impl.elem0.37f: %Y.type = impl_witness_access %I.lookup_impl_witness.99c, element0 [symbolic] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %impl.elem0.37f, @Z [symbolic] -// CHECK:STDOUT: %as_type.124: type = facet_access_type %impl.elem0.37f [symbolic] -// CHECK:STDOUT: %Z.facet.fd6: %Z.type = facet_value %as_type.124, (%Z.lookup_impl_witness) [symbolic] +// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0.37f [symbolic] +// CHECK:STDOUT: %Z.facet.fd6: %Z.type = facet_value %as_type, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.782: = complete_type_witness %empty_tuple.type [concrete] @@ -359,19 +359,16 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %pattern_type.be3: type = pattern_type %C.ffe [symbolic] // CHECK:STDOUT: %U: type = symbolic_binding U, 0 [symbolic] // CHECK:STDOUT: %Z.impl_witness.856: = impl_witness imports.%Z.impl_witness_table, @U.as.Z.impl(%U) [symbolic] -// CHECK:STDOUT: %.3cb: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type.124) [symbolic] -// CHECK:STDOUT: %Z.impl_witness.907: = impl_witness imports.%Z.impl_witness_table, @U.as.Z.impl(%as_type.124) [symbolic] +// CHECK:STDOUT: %.3cb: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic] +// CHECK:STDOUT: %Z.impl_witness.907: = impl_witness imports.%Z.impl_witness_table, @U.as.Z.impl(%as_type) [symbolic] // CHECK:STDOUT: %.Self.1dc: %I.type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness.c4b: = lookup_impl_witness %.Self.1dc, @I [symbolic_self] -// CHECK:STDOUT: %impl.elem0.66e: %Y.type = impl_witness_access %I.lookup_impl_witness.c4b, element0 [symbolic_self] -// CHECK:STDOUT: %as_type.ad8: type = facet_access_type %impl.elem0.66e [symbolic_self] -// CHECK:STDOUT: %Z.impl_witness.619: = impl_witness imports.%Z.impl_witness_table, @U.as.Z.impl(%as_type.ad8) [symbolic_self] -// CHECK:STDOUT: %.d02: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type.ad8) [symbolic_self] // CHECK:STDOUT: %I.WithSelf.F.type.29d: type = fn_type @I.WithSelf.F, @I.WithSelf(%.Self.1dc) [symbolic_self] // CHECK:STDOUT: %I.WithSelf.F.8ec: %I.WithSelf.F.type.29d = struct_value () [symbolic_self] // CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self.1dc [symbolic_self] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.c8f [concrete] +// CHECK:STDOUT: %I.lookup_impl_witness.c4b: = lookup_impl_witness %.Self.1dc, @I [symbolic_self] +// CHECK:STDOUT: %impl.elem0.66e: %Y.type = impl_witness_access %I.lookup_impl_witness.c4b, element0 [symbolic_self] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %Y.impl_witness.d43: = impl_witness imports.%Y.impl_witness_table, @T.as.Y.impl(%T) [symbolic] @@ -593,9 +590,9 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.651)] // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %Self, @I [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness.99c)] // CHECK:STDOUT: %impl.elem0: %Y.type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0 (constants.%impl.elem0.37f)] -// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0 [symbolic = %as_type (constants.%as_type.124)] -// CHECK:STDOUT: %.1: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic = %.1 (constants.%.3cb)] +// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0 [symbolic = %as_type (constants.%as_type)] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %impl.elem0, @Z [symbolic = %Z.lookup_impl_witness (constants.%Z.lookup_impl_witness)] +// CHECK:STDOUT: %.1: require_specific_def_type = require_specific_def @U.as.Z.impl(%as_type) [symbolic = %.1 (constants.%.3cb)] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %as_type, (%Z.lookup_impl_witness) [symbolic = %Z.facet (constants.%Z.facet.fd6)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Z.facet) [symbolic = %C (constants.%C.ffe)] // CHECK:STDOUT: %pattern_type: type = pattern_type %C [symbolic = %pattern_type (constants.%pattern_type.be3)] @@ -619,10 +616,6 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: specific @I.WithSelf(constants.%Self.651) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self => constants.%Self.651 -// CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.lookup_impl_witness.99c -// CHECK:STDOUT: %impl.elem0 => constants.%impl.elem0.37f -// CHECK:STDOUT: %as_type => constants.%as_type.124 -// CHECK:STDOUT: %.1 => constants.%.3cb // CHECK:STDOUT: %I.WithSelf.F.type => constants.%I.WithSelf.F.type.a1f // CHECK:STDOUT: %I.WithSelf.F => constants.%I.WithSelf.F.cc3 // CHECK:STDOUT: } @@ -648,8 +641,8 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %Z.impl_witness => constants.%Z.impl_witness.856 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @U.as.Z.impl(constants.%as_type.124) { -// CHECK:STDOUT: %U => constants.%as_type.124 +// CHECK:STDOUT: specific @U.as.Z.impl(constants.%as_type) { +// CHECK:STDOUT: %U => constants.%as_type // CHECK:STDOUT: %Z.impl_witness => constants.%Z.impl_witness.907 // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -659,9 +652,9 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %Self => constants.%Self.651 // CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.lookup_impl_witness.99c // CHECK:STDOUT: %impl.elem0 => constants.%impl.elem0.37f -// CHECK:STDOUT: %as_type => constants.%as_type.124 -// CHECK:STDOUT: %.1 => constants.%.3cb +// CHECK:STDOUT: %as_type => constants.%as_type // CHECK:STDOUT: %Z.lookup_impl_witness => constants.%Z.lookup_impl_witness +// CHECK:STDOUT: %.1 => constants.%.3cb // CHECK:STDOUT: %Z.facet => constants.%Z.facet.fd6 // CHECK:STDOUT: %C => constants.%C.ffe // CHECK:STDOUT: %pattern_type => constants.%pattern_type.be3 @@ -670,21 +663,10 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: specific @I.WithSelf(constants.%.Self.1dc) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self => constants.%.Self.1dc -// CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.lookup_impl_witness.c4b -// CHECK:STDOUT: %impl.elem0 => constants.%impl.elem0.66e -// CHECK:STDOUT: %as_type => constants.%as_type.ad8 -// CHECK:STDOUT: %.1 => constants.%.d02 // CHECK:STDOUT: %I.WithSelf.F.type => constants.%I.WithSelf.F.type.29d // CHECK:STDOUT: %I.WithSelf.F => constants.%I.WithSelf.F.8ec // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @U.as.Z.impl(constants.%as_type.ad8) { -// CHECK:STDOUT: %U => constants.%as_type.ad8 -// CHECK:STDOUT: %Z.impl_witness => constants.%Z.impl_witness.619 -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @T.as.Y.impl(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %Y.impl_witness => constants.%Y.impl_witness.d43 @@ -725,10 +707,6 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: specific @I.WithSelf(constants.%I.facet) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Self => constants.%I.facet -// CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.impl_witness -// CHECK:STDOUT: %impl.elem0 => constants.%Y.facet -// CHECK:STDOUT: %as_type => constants.%empty_tuple.type -// CHECK:STDOUT: %.1 => constants.%.194 // CHECK:STDOUT: %I.WithSelf.F.type => constants.%I.WithSelf.F.type.a33 // CHECK:STDOUT: %I.WithSelf.F => constants.%I.WithSelf.F.b0f // CHECK:STDOUT: } @@ -738,8 +716,8 @@ impl forall [N:! E] D(N) as I where .Assoc = () { // CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.impl_witness // CHECK:STDOUT: %impl.elem0 => constants.%Y.facet // CHECK:STDOUT: %as_type => constants.%empty_tuple.type -// CHECK:STDOUT: %.1 => constants.%.194 // CHECK:STDOUT: %Z.lookup_impl_witness => constants.%Z.impl_witness.db1 +// CHECK:STDOUT: %.1 => constants.%.194 // CHECK:STDOUT: %Z.facet => constants.%Z.facet.8bd // CHECK:STDOUT: %C => constants.%C.a44 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.479 diff --git a/toolchain/check/testdata/impl/incomplete.carbon b/toolchain/check/testdata/impl/incomplete.carbon index 6aeaff1d7ae1..b415228875d3 100644 --- a/toolchain/check/testdata/impl/incomplete.carbon +++ b/toolchain/check/testdata/impl/incomplete.carbon @@ -897,9 +897,7 @@ interface B { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Y.WithSelf(constants.%Self.550) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } +// CHECK:STDOUT: specific @Y.WithSelf(constants.%Self.550) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Y.WithSelf.Self.binding.as_type.impls.Z.type.require(constants.%Self.550) { // CHECK:STDOUT: %Self => constants.%Self.550 diff --git a/toolchain/check/testdata/impl/lookup/generic.carbon b/toolchain/check/testdata/impl/lookup/generic.carbon index 2a1fdb702294..8d23350913a9 100644 --- a/toolchain/check/testdata/impl/lookup/generic.carbon +++ b/toolchain/check/testdata/impl/lookup/generic.carbon @@ -386,8 +386,8 @@ fn G(x: A) { // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.2d4: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.74e: %ptr.as.Copy.impl.Op.type.2d4 = struct_value () [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet.c25 [symbolic] @@ -559,8 +559,8 @@ fn G(x: A) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %ptr.loc9_14 [symbolic = %require_complete (constants.%require_complete.ef1)] -// CHECK:STDOUT: %.loc9_37.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T) [symbolic = %.loc9_37.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc9_14, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc9_37.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T) [symbolic = %.loc9_37.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc9_14, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc9_37.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc9_37.2 (constants.%.299)] @@ -662,8 +662,8 @@ fn G(x: A) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete => constants.%complete_type -// CHECK:STDOUT: %.loc9_37.1 => constants.%.07c // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.3fd +// CHECK:STDOUT: %.loc9_37.1 => constants.%.07c // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.111 // CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.514 // CHECK:STDOUT: %.loc9_37.2 => constants.%.237 diff --git a/toolchain/check/testdata/impl/lookup/impl_forall.carbon b/toolchain/check/testdata/impl/lookup/impl_forall.carbon index 5093f18db80e..24143b06cca6 100644 --- a/toolchain/check/testdata/impl/lookup/impl_forall.carbon +++ b/toolchain/check/testdata/impl/lookup/impl_forall.carbon @@ -70,8 +70,8 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.2d4455.1: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.74e93b.1: %ptr.as.Copy.impl.Op.type.2d4455.1 = struct_value () [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f8f9.2, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f8f9.2, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet.c25 [symbolic] @@ -88,11 +88,11 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %I.assoc_type.76c031.3: type = assoc_entity_type @I, @I(%W) [symbolic] // CHECK:STDOUT: %assoc0.203667.3: %I.assoc_type.76c031.3 = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [symbolic] // CHECK:STDOUT: %require_complete.e360af.2: = require_complete_type %I.type.1ab3e4.3 [symbolic] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %A.95c0c7.3, @I, @I(%W) [symbolic] // CHECK:STDOUT: %I.impl_witness.f3f3bd.2: = impl_witness @A.as.I.impl.%I.impl_witness_table, @A.as.I.impl(%W) [symbolic] // CHECK:STDOUT: %A.as.I.impl.F.type.58747b.2: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%W) [symbolic] // CHECK:STDOUT: %A.as.I.impl.F.afeb91.2: %A.as.I.impl.F.type.58747b.2 = struct_value () [symbolic] // CHECK:STDOUT: %.0fe: require_specific_def_type = require_specific_def @A.as.I.impl(%W) [symbolic] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %A.95c0c7.3, @I, @I(%W) [symbolic] // CHECK:STDOUT: %I.facet.558: %I.type.1ab3e4.3 = facet_value %A.95c0c7.3, (%I.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %I.WithSelf.F.type.912: type = fn_type @I.WithSelf.F, @I.WithSelf(%W, %I.facet.558) [symbolic] // CHECK:STDOUT: %.695: type = fn_type_with_self_type %I.WithSelf.F.type.912, %I.facet.558 [symbolic] @@ -203,8 +203,8 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %require_complete.loc13_16: = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.fd6)] // CHECK:STDOUT: %require_complete.loc13_30: = require_complete_type %ptr.loc13_30.1 [symbolic = %require_complete.loc13_30 (constants.%require_complete.ef162c.1)] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.8a20fa.2)] -// CHECK:STDOUT: %.loc14_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V) [symbolic = %.loc14_12.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc13_30.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc14_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V) [symbolic = %.loc14_12.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc13_30.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc14_12.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc14_12.2 (constants.%.299)] @@ -235,8 +235,8 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %require_complete.loc21: = require_complete_type %I.type.loc21_17.2 [symbolic = %require_complete.loc21 (constants.%require_complete.e360af.2)] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I, @I(%W.loc19_16.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.76c031.3)] // CHECK:STDOUT: %assoc0: @TestGeneric.%I.assoc_type (%I.assoc_type.76c031.3) = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [symbolic = %assoc0 (constants.%assoc0.203667.3)] -// CHECK:STDOUT: %.loc21_11.2: require_specific_def_type = require_specific_def @A.as.I.impl(%W.loc19_16.1) [symbolic = %.loc21_11.2 (constants.%.0fe)] // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %A.loc19_32.1, @I, @I(%W.loc19_16.1) [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness)] +// CHECK:STDOUT: %.loc21_11.2: require_specific_def_type = require_specific_def @A.as.I.impl(%W.loc19_16.1) [symbolic = %.loc21_11.2 (constants.%.0fe)] // CHECK:STDOUT: %I.facet: @TestGeneric.%I.type.loc21_17.2 (%I.type.1ab3e4.3) = facet_value %A.loc19_32.1, (%I.lookup_impl_witness) [symbolic = %I.facet (constants.%I.facet.558)] // CHECK:STDOUT: %I.WithSelf.F.type: type = fn_type @I.WithSelf.F, @I.WithSelf(%W.loc19_16.1, %I.facet) [symbolic = %I.WithSelf.F.type (constants.%I.WithSelf.F.type.912)] // CHECK:STDOUT: %.loc21_11.3: type = fn_type_with_self_type %I.WithSelf.F.type, %I.facet [symbolic = %.loc21_11.3 (constants.%.695)] @@ -346,8 +346,8 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %require_complete.loc13_16 => constants.%complete_type.0a6 // CHECK:STDOUT: %require_complete.loc13_30 => constants.%complete_type.38e // CHECK:STDOUT: %A.elem => constants.%A.elem.599 -// CHECK:STDOUT: %.loc14_12.1 => constants.%.07c // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.3fd +// CHECK:STDOUT: %.loc14_12.1 => constants.%.07c // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.111 // CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.514 // CHECK:STDOUT: %.loc14_12.2 => constants.%.237 diff --git a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon index 3fd60ed784f9..dc3c5cee5136 100644 --- a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon +++ b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon @@ -539,6 +539,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %assoc0.ae8: %ImplicitAs.assoc_type.ac6 = assoc_entity element0, imports.%Core.import_ref.201 [symbolic] // CHECK:STDOUT: %require_complete.591: = require_complete_type %ImplicitAs.type.7e4 [symbolic] // CHECK:STDOUT: %assoc0.843: %ImplicitAs.assoc_type.ff3 = assoc_entity element0, imports.%Core.import_ref.cc1 [symbolic] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %T.fe5, @ImplicitAs, @ImplicitAs(%impl.elem0.a5e) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -756,6 +757,7 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %require_complete.loc22_23: = require_complete_type %ImplicitAs.type.loc22_23.2 [symbolic = %require_complete.loc22_23 (constants.%require_complete.591)] // CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%impl.elem0.loc22_18.2) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.ac6)] // CHECK:STDOUT: %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.ac6) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.ae8)] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %T.loc14_6.1, @ImplicitAs, @ImplicitAs(%impl.elem0.loc22_18.2) [symbolic = %ImplicitAs.lookup_impl_witness (constants.%ImplicitAs.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%t.param: @F.%T.binding.as_type (%T.binding.as_type)) { // CHECK:STDOUT: !entry: @@ -915,8 +917,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %require_complete.944: = require_complete_type %T.67d [symbolic] // CHECK:STDOUT: %require_complete.ef1: = require_complete_type %ptr.e8f8f9.2 [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f8f9.2, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e8f8f9.2, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet [symbolic] @@ -1040,8 +1042,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc9_16: = require_complete_type %T.loc9_6.1 [symbolic = %require_complete.loc9_16 (constants.%require_complete.944)] // CHECK:STDOUT: %require_complete.loc9_30: = require_complete_type %ptr [symbolic = %require_complete.loc9_30 (constants.%require_complete.ef1)] -// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc9_6.1) [symbolic = %.loc10_10.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc9_6.1) [symbolic = %.loc10_10.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc10_10.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc10_10.2 (constants.%.299)] @@ -1141,8 +1143,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %require_complete.552: = require_complete_type %T.binding.as_type.3dc [symbolic] // CHECK:STDOUT: %require_complete.c1c: = require_complete_type %ptr.a86 [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.54b: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type.3dc) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.3c7: = lookup_impl_witness %ptr.a86, @Copy [symbolic] +// CHECK:STDOUT: %.54b: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type.3dc) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.a86, (%Copy.lookup_impl_witness.3c7) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.207: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.382: type = fn_type_with_self_type %Copy.WithSelf.Op.type.207, %Copy.facet [symbolic] @@ -1269,8 +1271,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc9_15: = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_15 (constants.%require_complete.552)] // CHECK:STDOUT: %require_complete.loc9_29: = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.c1c)] -// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.1 (constants.%.54b)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.3c7)] +// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.1 (constants.%.54b)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.207)] // CHECK:STDOUT: %.loc10_10.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc10_10.2 (constants.%.382)] @@ -1370,8 +1372,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %require_complete.552: = require_complete_type %T.binding.as_type.3dc [symbolic] // CHECK:STDOUT: %require_complete.c1c: = require_complete_type %ptr.a86 [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.54b: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type.3dc) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.3c7: = lookup_impl_witness %ptr.a86, @Copy [symbolic] +// CHECK:STDOUT: %.54b: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type.3dc) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.a86, (%Copy.lookup_impl_witness.3c7) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.207: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.382: type = fn_type_with_self_type %Copy.WithSelf.Op.type.207, %Copy.facet [symbolic] @@ -1497,8 +1499,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc9_15: = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_15 (constants.%require_complete.552)] // CHECK:STDOUT: %require_complete.loc9_29: = require_complete_type %ptr [symbolic = %require_complete.loc9_29 (constants.%require_complete.c1c)] -// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.1 (constants.%.54b)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.3c7)] +// CHECK:STDOUT: %.loc10_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.binding.as_type) [symbolic = %.loc10_10.1 (constants.%.54b)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.207)] // CHECK:STDOUT: %.loc10_10.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc10_10.2 (constants.%.382)] diff --git a/toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon b/toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon new file mode 100644 index 000000000000..18e191fca532 --- /dev/null +++ b/toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon @@ -0,0 +1,44 @@ +// 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 +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon + +// --- construct_facet_value_inside_definition.carbon +library "[[@TEST_NAME]]"; + +interface I { + let U:! type; + fn F() -> U; +} + +class C { adapt {}; } + +impl forall [T:! type] T as I where .U = C { + // `T as I` does an impl lookup to form a FacetValue, which must find the impl + // being defined and use that. The witness must be a final witness in order to + // know that `U` is `C`. + fn F() -> (T as I).U { return {} as C; } +} + +// --- construct_facet_value_from_self_inside_definition.carbon +library "[[@TEST_NAME]]"; + +interface I { + let U:! type; + fn F() -> U; +} + +class C { adapt {}; } + +impl forall [T:! type] T as I where .U = C { + // `Self as I` is a symbolic facet value specified in the interface-with-self + // specific, and then monomorphized with the self type of the impl. + fn F() -> (Self as I).U { return {} as C; } +} diff --git a/toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon b/toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon new file mode 100644 index 000000000000..6a636fb3546f --- /dev/null +++ b/toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon @@ -0,0 +1,31 @@ +// 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 +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon + +// --- fail_todo_name_lookup_into_impl_as_target.carbon +library "[[@TEST_NAME]]"; + +interface I { + let U:! type; + fn F() -> U; +} + +class C { adapt {}; } + +impl forall [T:! type] T as I where .U = C { + // TODO: We should do name lookup into `I` inside the body of an `impl as I`, + // where we would find `U`. + // CHECK:STDERR: fail_todo_name_lookup_into_impl_as_target.carbon:[[@LINE+4]]:13: error: name `U` not found [NameNotFound] + // CHECK:STDERR: fn F() -> U { return {} as C; } + // CHECK:STDERR: ^ + // CHECK:STDERR: + fn F() -> U { return {} as C; } +} diff --git a/toolchain/check/testdata/interface/as_type_of_type.carbon b/toolchain/check/testdata/interface/as_type_of_type.carbon index a87bd3451c67..8653286d26dd 100644 --- a/toolchain/check/testdata/interface/as_type_of_type.carbon +++ b/toolchain/check/testdata/interface/as_type_of_type.carbon @@ -44,8 +44,8 @@ fn F(T:! Empty) { // CHECK:STDOUT: %require_complete.315: = require_complete_type %ptr [symbolic] // CHECK:STDOUT: %pattern_type.fd9: type = pattern_type %ptr [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.type: type = facet_type <@DefaultOrUnformed> [concrete] -// CHECK:STDOUT: %.a5e: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %ptr, @DefaultOrUnformed [symbolic] +// CHECK:STDOUT: %.a5e: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.facet: %DefaultOrUnformed.type = facet_value %ptr, (%DefaultOrUnformed.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type.478: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet) [symbolic] // CHECK:STDOUT: %.fb3: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type.478, %DefaultOrUnformed.facet [symbolic] @@ -131,8 +131,8 @@ fn F(T:! Empty) { // CHECK:STDOUT: %ptr.loc22_18.2: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc22_18.2 (constants.%ptr)] // CHECK:STDOUT: %require_complete: = require_complete_type %ptr.loc22_18.2 [symbolic = %require_complete (constants.%require_complete.315)] // CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.loc22_18.2 [symbolic = %pattern_type (constants.%pattern_type.fd9)] -// CHECK:STDOUT: %.loc22_19.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr.loc22_18.2) [symbolic = %.loc22_19.3 (constants.%.a5e)] // CHECK:STDOUT: %DefaultOrUnformed.lookup_impl_witness: = lookup_impl_witness %ptr.loc22_18.2, @DefaultOrUnformed [symbolic = %DefaultOrUnformed.lookup_impl_witness (constants.%DefaultOrUnformed.lookup_impl_witness)] +// CHECK:STDOUT: %.loc22_19.3: require_specific_def_type = require_specific_def @T.as.DefaultOrUnformed.impl(%ptr.loc22_18.2) [symbolic = %.loc22_19.3 (constants.%.a5e)] // CHECK:STDOUT: %DefaultOrUnformed.facet.loc22_19.2: %DefaultOrUnformed.type = facet_value %ptr.loc22_18.2, (%DefaultOrUnformed.lookup_impl_witness) [symbolic = %DefaultOrUnformed.facet.loc22_19.2 (constants.%DefaultOrUnformed.facet)] // CHECK:STDOUT: %DefaultOrUnformed.WithSelf.Op.type: type = fn_type @DefaultOrUnformed.WithSelf.Op, @DefaultOrUnformed.WithSelf(%DefaultOrUnformed.facet.loc22_19.2) [symbolic = %DefaultOrUnformed.WithSelf.Op.type (constants.%DefaultOrUnformed.WithSelf.Op.type.478)] // CHECK:STDOUT: %.loc22_19.4: type = fn_type_with_self_type %DefaultOrUnformed.WithSelf.Op.type, %DefaultOrUnformed.facet.loc22_19.2 [symbolic = %.loc22_19.4 (constants.%.fb3)] diff --git a/toolchain/check/testdata/interface/compound_member_access.carbon b/toolchain/check/testdata/interface/compound_member_access.carbon index 675b71cc027d..24c636562604 100644 --- a/toolchain/check/testdata/interface/compound_member_access.carbon +++ b/toolchain/check/testdata/interface/compound_member_access.carbon @@ -552,6 +552,7 @@ fn Works() { // CHECK:STDOUT: %require_complete.57854f.2: = require_complete_type %V.binding.as_type [symbolic] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %V, @ImplicitAs, @ImplicitAs(%K2.type) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -661,6 +662,7 @@ fn Works() { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type %V.binding.as_type [symbolic = %require_complete (constants.%require_complete.57854f.2)] +// CHECK:STDOUT: %ImplicitAs.lookup_impl_witness: = lookup_impl_witness %V.loc14_14.1, @ImplicitAs, @ImplicitAs(constants.%K2.type) [symbolic = %ImplicitAs.lookup_impl_witness (constants.%ImplicitAs.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%y.param: @Compound3.%V.binding.as_type (%V.binding.as_type)) { // CHECK:STDOUT: !entry: @@ -1082,13 +1084,13 @@ fn Works() { // CHECK:STDOUT: %L2.WithSelf.S2.type.68b: type = fn_type @L2.WithSelf.S2, @L2.WithSelf(%T) [symbolic] // CHECK:STDOUT: %L2.WithSelf.S2.470: %L2.WithSelf.S2.type.68b = struct_value () [symbolic] // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] -// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T, @L2 [symbolic] +// CHECK:STDOUT: %L2.lookup_impl_witness.074: = lookup_impl_witness %T, @L2 [symbolic] // CHECK:STDOUT: %.f8e: type = fn_type_with_self_type %L2.WithSelf.R2.type.ba3, %T [symbolic] -// CHECK:STDOUT: %impl.elem0: %.f8e = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %impl.elem0: %.f8e = impl_witness_access %L2.lookup_impl_witness.074, element0 [symbolic] // CHECK:STDOUT: %pattern_type.0fc: type = pattern_type %T.binding.as_type [symbolic] // CHECK:STDOUT: %specific_impl_fn.b6c: = specific_impl_function %impl.elem0, @L2.WithSelf.R2(%T) [symbolic] // CHECK:STDOUT: %.b1c: type = fn_type_with_self_type %L2.WithSelf.S2.type.68b, %T [symbolic] -// CHECK:STDOUT: %impl.elem1: %.b1c = impl_witness_access %L2.lookup_impl_witness, element1 [symbolic] +// CHECK:STDOUT: %impl.elem1: %.b1c = impl_witness_access %L2.lookup_impl_witness.074, element1 [symbolic] // CHECK:STDOUT: %specific_impl_fn.b67: = specific_impl_function %impl.elem1, @L2.WithSelf.S2(%T) [symbolic] // CHECK:STDOUT: %V: %L2.type = symbolic_binding V, 0 [symbolic] // CHECK:STDOUT: %Compound5.type: type = fn_type @Compound5 [concrete] @@ -1193,7 +1195,7 @@ fn Works() { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc10_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] -// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T.loc10_12.1, @L2 [symbolic = %L2.lookup_impl_witness (constants.%L2.lookup_impl_witness)] +// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T.loc10_12.1, @L2 [symbolic = %L2.lookup_impl_witness (constants.%L2.lookup_impl_witness.074)] // CHECK:STDOUT: %L2.WithSelf.R2.type: type = fn_type @L2.WithSelf.R2, @L2.WithSelf(%T.loc10_12.1) [symbolic = %L2.WithSelf.R2.type (constants.%L2.WithSelf.R2.type.ba3)] // CHECK:STDOUT: %.loc18_4.2: type = fn_type_with_self_type %L2.WithSelf.R2.type, %T.loc10_12.1 [symbolic = %.loc18_4.2 (constants.%.f8e)] // CHECK:STDOUT: %impl.elem0.loc18_4.2: @Simple5.%.loc18_4.2 (%.f8e) = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] @@ -1209,14 +1211,14 @@ fn Works() { // CHECK:STDOUT: %T.as_type.loc18: type = facet_access_type %T.ref.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] // CHECK:STDOUT: %.loc18_4.1: type = converted %T.ref.loc18, %T.as_type.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] // CHECK:STDOUT: %R2.ref: %L2.assoc_type = name_ref R2, @L2.WithSelf.%assoc0 [concrete = constants.%assoc0] -// CHECK:STDOUT: %impl.elem0.loc18_4.1: @Simple5.%.loc18_4.2 (%.f8e) = impl_witness_access constants.%L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @Simple5.%.loc18_4.2 (%.f8e) = impl_witness_access constants.%L2.lookup_impl_witness.074, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] // CHECK:STDOUT: %specific_impl_fn.loc18_4.1: = specific_impl_function %impl.elem0.loc18_4.1, @L2.WithSelf.R2(constants.%T) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.b6c)] // CHECK:STDOUT: %L2.WithSelf.R2.call: init %empty_tuple.type = call %specific_impl_fn.loc18_4.1() // CHECK:STDOUT: %T.ref.loc26: %L2.type = name_ref T, %T.loc10_12.2 [symbolic = %T.loc10_12.1 (constants.%T)] // CHECK:STDOUT: %T.as_type.loc26: type = facet_access_type %T.ref.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] // CHECK:STDOUT: %.loc26_4.1: type = converted %T.ref.loc26, %T.as_type.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] // CHECK:STDOUT: %S2.ref: %L2.assoc_type = name_ref S2, @L2.WithSelf.%assoc1 [concrete = constants.%assoc1] -// CHECK:STDOUT: %impl.elem1.loc26_4.1: @Simple5.%.loc26_4.2 (%.b1c) = impl_witness_access constants.%L2.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] +// CHECK:STDOUT: %impl.elem1.loc26_4.1: @Simple5.%.loc26_4.2 (%.b1c) = impl_witness_access constants.%L2.lookup_impl_witness.074, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] // CHECK:STDOUT: %specific_impl_fn.loc26_4.1: = specific_impl_function %impl.elem1.loc26_4.1, @L2.WithSelf.S2(constants.%T) [symbolic = %specific_impl_fn.loc26_4.2 (constants.%specific_impl_fn.b67)] // CHECK:STDOUT: %L2.WithSelf.S2.call: init %empty_tuple.type = call %specific_impl_fn.loc26_4.1() // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon b/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon index 353666ab3c48..f0ad3e610ec7 100644 --- a/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon +++ b/toolchain/check/testdata/interface/fail_assoc_const_alias.carbon @@ -82,8 +82,8 @@ interface C { // CHECK:STDOUT: %J2.type: type = facet_type <@J2> [concrete] // CHECK:STDOUT: %Self.4a7: %J2.type = symbolic_binding Self, 0 [symbolic] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self.4a7 [symbolic] -// CHECK:STDOUT: %.ef7: require_specific_def_type = require_specific_def @V.binding.as_type.as.I2.impl(%Self.4a7) [symbolic] // CHECK:STDOUT: %I2.lookup_impl_witness.d97: = lookup_impl_witness %Self.4a7, @I2 [symbolic] +// CHECK:STDOUT: %.ef7: require_specific_def_type = require_specific_def @V.binding.as_type.as.I2.impl(%Self.4a7) [symbolic] // CHECK:STDOUT: %I2.facet.7a5: %I2.type = facet_value %Self.binding.as_type, (%I2.lookup_impl_witness.d97) [symbolic] // CHECK:STDOUT: %impl.elem0.006: type = impl_witness_access %I2.lookup_impl_witness.d97, element0 [symbolic] // CHECK:STDOUT: %.805: Core.Form = init_form %impl.elem0.006 [symbolic] @@ -135,8 +135,8 @@ interface C { // CHECK:STDOUT: generic fn @J2.WithSelf.F2(@J2.%Self: %J2.type) { // CHECK:STDOUT: %Self: %J2.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.4a7)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] -// CHECK:STDOUT: %.loc14_14.1: require_specific_def_type = require_specific_def @V.binding.as_type.as.I2.impl(%Self) [symbolic = %.loc14_14.1 (constants.%.ef7)] // CHECK:STDOUT: %I2.lookup_impl_witness: = lookup_impl_witness %Self, @I2 [symbolic = %I2.lookup_impl_witness (constants.%I2.lookup_impl_witness.d97)] +// CHECK:STDOUT: %.loc14_14.1: require_specific_def_type = require_specific_def @V.binding.as_type.as.I2.impl(%Self) [symbolic = %.loc14_14.1 (constants.%.ef7)] // CHECK:STDOUT: %I2.facet.loc14_14.1: %I2.type = facet_value %Self.binding.as_type, (%I2.lookup_impl_witness) [symbolic = %I2.facet.loc14_14.1 (constants.%I2.facet.7a5)] // CHECK:STDOUT: %impl.elem0.loc14_14.1: type = impl_witness_access %I2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_14.1 (constants.%impl.elem0.006)] // CHECK:STDOUT: %.loc14_14.2: Core.Form = init_form %impl.elem0.loc14_14.1 [symbolic = %.loc14_14.2 (constants.%.805)] @@ -150,8 +150,8 @@ interface C { // CHECK:STDOUT: specific @J2.WithSelf.F2(constants.%Self.4a7) { // CHECK:STDOUT: %Self => constants.%Self.4a7 // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type -// CHECK:STDOUT: %.loc14_14.1 => constants.%.ef7 // CHECK:STDOUT: %I2.lookup_impl_witness => constants.%I2.lookup_impl_witness.d97 +// CHECK:STDOUT: %.loc14_14.1 => constants.%.ef7 // CHECK:STDOUT: %I2.facet.loc14_14.1 => constants.%I2.facet.7a5 // CHECK:STDOUT: %impl.elem0.loc14_14.1 => constants.%impl.elem0.006 // CHECK:STDOUT: %.loc14_14.2 => constants.%.805 diff --git a/toolchain/check/testdata/interface/fail_member_lookup.carbon b/toolchain/check/testdata/interface/fail_member_lookup.carbon index 04cd7cfc1511..815b4d5a0bf4 100644 --- a/toolchain/check/testdata/interface/fail_member_lookup.carbon +++ b/toolchain/check/testdata/interface/fail_member_lookup.carbon @@ -68,6 +68,7 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: %pattern_type.cb4: type = pattern_type %Different.type [concrete] // CHECK:STDOUT: %U: %Different.type = symbolic_binding U, 0 [symbolic] // CHECK:STDOUT: %U.binding.as_type: type = symbolic_binding_type U, 0, %U [symbolic] +// CHECK:STDOUT: %Interface.lookup_impl_witness: = lookup_impl_witness %U, @Interface [symbolic] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -167,6 +168,7 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: generic fn @G(%U.loc32_6.2: %Different.type) { // CHECK:STDOUT: %U.loc32_6.1: %Different.type = symbolic_binding U, 0 [symbolic = %U.loc32_6.1 (constants.%U)] // CHECK:STDOUT: %U.binding.as_type: type = symbolic_binding_type U, 0, %U.loc32_6.1 [symbolic = %U.binding.as_type (constants.%U.binding.as_type)] +// CHECK:STDOUT: %Interface.lookup_impl_witness: = lookup_impl_witness %U.loc32_6.1, @Interface [symbolic = %Interface.lookup_impl_witness (constants.%Interface.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn() -> ; // CHECK:STDOUT: } @@ -187,5 +189,6 @@ fn G(U:! Different) -> U.(Interface.T); // CHECK:STDOUT: specific @G(constants.%U) { // CHECK:STDOUT: %U.loc32_6.1 => constants.%U // CHECK:STDOUT: %U.binding.as_type => constants.%U.binding.as_type +// CHECK:STDOUT: %Interface.lookup_impl_witness => constants.%Interface.lookup_impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon b/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon index 26f25425b31f..ae6533501902 100644 --- a/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon +++ b/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon @@ -191,8 +191,8 @@ fn Interface.C.F[unused self: Self](U:! type, u: U*) -> U* { return u; } // CHECK:STDOUT: %require_complete.a31: = require_complete_type %C [symbolic] // CHECK:STDOUT: %require_complete.56d: = require_complete_type %ptr.18e [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %.f1d: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.091) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.484: = lookup_impl_witness %ptr.18e, @Copy [symbolic] +// CHECK:STDOUT: %.f1d: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.091) [symbolic] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.18e, (%Copy.lookup_impl_witness.484) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.be8: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] // CHECK:STDOUT: %.e5c: type = fn_type_with_self_type %Copy.WithSelf.Op.type.be8, %Copy.facet [symbolic] @@ -325,8 +325,8 @@ fn Interface.C.F[unused self: Self](U:! type, u: U*) -> U* { return u; } // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc20_29: = require_complete_type %C [symbolic = %require_complete.loc20_29 (constants.%require_complete.a31)] // CHECK:STDOUT: %require_complete.loc20_48: = require_complete_type %ptr.loc14_36.1 [symbolic = %require_complete.loc20_48 (constants.%require_complete.56d)] -// CHECK:STDOUT: %.loc20_69.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc14_22.1) [symbolic = %.loc20_69.1 (constants.%.f1d)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc14_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.484)] +// CHECK:STDOUT: %.loc20_69.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc14_22.1) [symbolic = %.loc20_69.1 (constants.%.f1d)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc14_36.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.be8)] // CHECK:STDOUT: %.loc20_69.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc20_69.2 (constants.%.e5c)] diff --git a/toolchain/check/testdata/interface/generic.carbon b/toolchain/check/testdata/interface/generic.carbon index 327342ab8394..a3ddde90c12b 100644 --- a/toolchain/check/testdata/interface/generic.carbon +++ b/toolchain/check/testdata/interface/generic.carbon @@ -474,6 +474,7 @@ fn F(unused T:! Generic((), ())) {} // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %Self.b24: %Generic.type.cb7 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.3ee [symbolic] +// CHECK:STDOUT: %Generic.lookup_impl_witness: = lookup_impl_witness %T.3ee, @Generic, @Generic(%A) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -565,6 +566,7 @@ fn F(unused T:! Generic((), ())) {} // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc10_6.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %Generic.lookup_impl_witness: = lookup_impl_witness %T.loc10_6.1, @Generic, @Generic(constants.%A) [symbolic = %Generic.lookup_impl_witness (constants.%Generic.lookup_impl_witness)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: diff --git a/toolchain/check/testdata/interface/generic_method.carbon b/toolchain/check/testdata/interface/generic_method.carbon index fba72d9b0342..3a329c1f5d55 100644 --- a/toolchain/check/testdata/interface/generic_method.carbon +++ b/toolchain/check/testdata/interface/generic_method.carbon @@ -144,8 +144,8 @@ fn CallIndirect() { // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.2d4455.1: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.74e93b.1: %ptr.as.Copy.impl.Op.type.2d4455.1 = struct_value () [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f8f9.1, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f8f9.1, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet.c25 [symbolic] @@ -429,8 +429,8 @@ fn CallIndirect() { // CHECK:STDOUT: %require_complete.loc16_19: = require_complete_type %ptr.loc16_22.1 [symbolic = %require_complete.loc16_19 (constants.%require_complete.ef162c.1)] // CHECK:STDOUT: %require_complete.loc16_37: = require_complete_type %tuple.type.loc16 [symbolic = %require_complete.loc16_37 (constants.%require_complete.034)] // CHECK:STDOUT: %tuple.type.loc17: type = tuple_type (constants.%empty_struct_type, constants.%empty_struct_type, %ptr.loc16_22.1) [symbolic = %tuple.type.loc17 (constants.%tuple.type.dd2)] -// CHECK:STDOUT: %.loc17_21.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc16_8.1) [symbolic = %.loc17_21.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc16_22.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc17_21.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc16_8.1) [symbolic = %.loc17_21.1 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc16_22.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc17_21.2: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc17_21.2 (constants.%.299)] @@ -668,8 +668,8 @@ fn CallIndirect() { // CHECK:STDOUT: %require_complete.loc16_19 => constants.%complete_type.543 // CHECK:STDOUT: %require_complete.loc16_37 => constants.%complete_type.28e // CHECK:STDOUT: %tuple.type.loc17 => constants.%tuple.type.0dd -// CHECK:STDOUT: %.loc17_21.1 => constants.%.157 // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.425 +// CHECK:STDOUT: %.loc17_21.1 => constants.%.157 // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.26e // CHECK:STDOUT: %Copy.WithSelf.Op.type => constants.%Copy.WithSelf.Op.type.a8b // CHECK:STDOUT: %.loc17_21.2 => constants.%.2ef diff --git a/toolchain/check/testdata/interface/member_lookup.carbon b/toolchain/check/testdata/interface/member_lookup.carbon index 2974597f2125..f46033c56129 100644 --- a/toolchain/check/testdata/interface/member_lookup.carbon +++ b/toolchain/check/testdata/interface/member_lookup.carbon @@ -80,8 +80,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 { // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.2d4: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.74e: %ptr.as.Copy.impl.Op.type.2d4 = struct_value () [symbolic] -// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.lookup_impl_witness.2e6: = lookup_impl_witness %ptr.e8f, @Copy [symbolic] +// CHECK:STDOUT: %.2f2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.67d) [symbolic] // CHECK:STDOUT: %Copy.facet.c25: %Copy.type = facet_value %ptr.e8f, (%Copy.lookup_impl_witness.2e6) [symbolic] // CHECK:STDOUT: %Copy.WithSelf.Op.type.d82: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.c25) [symbolic] // CHECK:STDOUT: %.299: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d82, %Copy.facet.c25 [symbolic] @@ -236,8 +236,8 @@ fn AccessMissingConcrete(I:! Interface(i32)) -> i32 { // CHECK:STDOUT: %assoc0: @AccessGeneric.%Interface.assoc_type (%Interface.assoc_type.5a2) = assoc_entity element0, @Interface.WithSelf.%X [symbolic = %assoc0 (constants.%assoc0.b59)] // CHECK:STDOUT: %Interface.lookup_impl_witness: = lookup_impl_witness %I.loc8_28.1, @Interface, @Interface(%T.loc8_18.1) [symbolic = %Interface.lookup_impl_witness (constants.%Interface.lookup_impl_witness.9f1)] // CHECK:STDOUT: %impl.elem0.loc9_11.3: @AccessGeneric.%ptr.loc8_50.1 (%ptr.e8f) = impl_witness_access %Interface.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_11.3 (constants.%impl.elem0.117)] -// CHECK:STDOUT: %.loc9_11.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc8_18.1) [symbolic = %.loc9_11.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc8_50.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)] +// CHECK:STDOUT: %.loc9_11.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc8_18.1) [symbolic = %.loc9_11.3 (constants.%.2f2)] // CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc8_50.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.c25)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.d82)] // CHECK:STDOUT: %.loc9_11.4: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet [symbolic = %.loc9_11.4 (constants.%.299)] diff --git a/toolchain/check/testdata/named_constraint/empty_generic.carbon b/toolchain/check/testdata/named_constraint/empty_generic.carbon index 2b763185354b..431f0a3e096d 100644 --- a/toolchain/check/testdata/named_constraint/empty_generic.carbon +++ b/toolchain/check/testdata/named_constraint/empty_generic.carbon @@ -53,7 +53,6 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %empty_struct.a40: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %Self.31c17c.2: %Empty.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %empty_struct.type.facet: %type = facet_value %empty_struct_type, () [concrete] // CHECK:STDOUT: %Empty.facet.76f: %Empty.type.d682d6.2 = facet_value %empty_struct_type, () [symbolic] // CHECK:STDOUT: %F.specific_fn.5f9: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.76f) [symbolic] @@ -62,6 +61,7 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: %F.specific_fn.ff8: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.2cb) [symbolic] // CHECK:STDOUT: %Empty.facet.4f8: %Empty.type.d682d6.2 = facet_value %T.binding.as_type, () [symbolic] // CHECK:STDOUT: %F.specific_fn.55f: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.4f8) [symbolic] +// CHECK:STDOUT: %Self.31c17c.2: %Empty.type.d682d6.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %F.specific_fn.5c5: = specific_function %F, @F(%T.binding.as_type, %U.e1f642.2) [symbolic] // CHECK:STDOUT: %facet_value.ed5: %type = facet_value %V, () [symbolic] // CHECK:STDOUT: %Empty.facet.ed5: %Empty.type.d682d6.2 = facet_value %V, () [symbolic] @@ -255,10 +255,6 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: %V.loc20_27.1 => constants.%V // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Empty.WithSelf(constants.%T.binding.as_type, constants.%Self.31c17c.1) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @Empty.WithSelf(constants.%T.binding.as_type, constants.%empty_struct.type.facet) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } @@ -298,6 +294,10 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Empty.WithSelf(constants.%T.binding.as_type, constants.%Self.31c17c.1) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.binding.as_type, constants.%U.e1f642.2) { // CHECK:STDOUT: %T.loc18_6.1 => constants.%T.binding.as_type // CHECK:STDOUT: %Empty.type.loc18_34.1 => constants.%Empty.type.d682d6.2 diff --git a/toolchain/check/testdata/named_constraint/incomplete.carbon b/toolchain/check/testdata/named_constraint/incomplete.carbon index 70d30cb59549..fa20c1c9bbd2 100644 --- a/toolchain/check/testdata/named_constraint/incomplete.carbon +++ b/toolchain/check/testdata/named_constraint/incomplete.carbon @@ -2,7 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon // // AUTOUPDATE // TIP: To test this file alone, run: @@ -15,19 +15,10 @@ library "[[@TEST_NAME]]"; interface Z {} +// An incomplete constraint is a valid type for a symbolic facet, and is just +// not able to provide any witness for an impl lookup on that facet. constraint N; fn F(T:! N) { - // TODO: The failed-to-identify error should be a note under the convert error - // instead of being a separate error. This can be done by making a top-level - // convert error as a Context for specific errors that happen during convert. - // - // CHECK:STDERR: fail_incomplete_constraint_in_impl_lookup.carbon:[[@LINE+11]]:3: error: facet type of value `T` can not be identified [ImplLookupInUnidentifiedFacetTypeOfQuerySelf] - // CHECK:STDERR: T as Z; - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: fail_incomplete_constraint_in_impl_lookup.carbon:[[@LINE-9]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] - // CHECK:STDERR: constraint N; - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: // CHECK:STDERR: fail_incomplete_constraint_in_impl_lookup.carbon:[[@LINE+4]]:3: error: cannot convert type `T` that implements `N` into type implementing `Z` [ConversionFailureFacetToFacet] // CHECK:STDERR: T as Z; // CHECK:STDERR: ^~~~~~ @@ -35,33 +26,103 @@ fn F(T:! N) { T as Z; } -// --- fail_todo_does_not_diagnose_identify_failure_in_deduce.carbon +// --- fail_does_not_diagnose_identify_failure_in_deduce.carbon library "[[@TEST_NAME]]"; constraint N; interface Z {} -// Since N is an incomplete constraint, it can not be identified for impl lookup -// to determine if C implements N. +// Since N is an incomplete constraint, it can not be identified as a target for +// impl lookup to determine if C implements N. No diagnostic is attached to the +// impl when the lookup fails, we simply fail to convert. impl forall [T:! N] T as Z {} class C; fn F() { - // TODO: The "can not be identified" diagnostic should not occur here. That - // diagnostic happened during deduction, which means to suppress diagnostics. - // Only the convert error should be emitted. - // - // CHECK:STDERR: fail_todo_does_not_diagnose_identify_failure_in_deduce.carbon:[[@LINE+11]]:3: error: facet type `N` can not be identified [ImplLookupInUnidentifiedFacetType] - // CHECK:STDERR: C as Z; - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: fail_todo_does_not_diagnose_identify_failure_in_deduce.carbon:[[@LINE-17]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] - // CHECK:STDERR: constraint N; - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_does_not_diagnose_identify_failure_in_deduce.carbon:[[@LINE+4]]:3: error: cannot convert type `C` into type implementing `Z` [ConversionFailureTypeToFacet] + // CHECK:STDERR: fail_does_not_diagnose_identify_failure_in_deduce.carbon:[[@LINE+4]]:3: error: cannot convert type `C` into type implementing `Z` [ConversionFailureTypeToFacet] // CHECK:STDERR: C as Z; // CHECK:STDERR: ^~~~~~ // CHECK:STDERR: C as Z; } + +// --- constraint_completed_after_deducing_impl_refers_to_it.carbon +library "[[@TEST_NAME]]"; + +constraint N; + +interface Z {} +// N is incomplete here, but that's okay. We don't need it to be identified +// until a lookup tries to use this impl. +impl forall [T:! N] T as Z {} + +class C; + +// N is now identified, so it can be the target of a convertion, such as for +// deducing `T` in the impl above. +constraint N {} + +fn F() { + C as Z; +} + +// --- fail_impl_lookup_target_not_identified.carbon +library "[[@TEST_NAME]]"; + +constraint Z; + +fn AsZ(unused T:! Z) {} + +fn F() { + // Converting to facet type `Z` requires `Z` to be identified. + // CHECK:STDERR: fail_impl_lookup_target_not_identified.carbon:[[@LINE+10]]:3: error: facet type `Z` can not be identified [ImplLookupInUnidentifiedFacetType] + // CHECK:STDERR: AsZ(()); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_impl_lookup_target_not_identified.carbon:[[@LINE-9]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] + // CHECK:STDERR: constraint Z; + // CHECK:STDERR: ^~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_lookup_target_not_identified.carbon:[[@LINE-10]]:15: note: initializing generic parameter `T` declared here [InitializingGenericParam] + // CHECK:STDERR: fn AsZ(unused T:! Z) {} + // CHECK:STDERR: ^ + // CHECK:STDERR: + AsZ(()); +} + +// --- fail_incomplete_self.carbon +library "[[@TEST_NAME]]"; + +// Returning a facet of type `W` requires `W` to be complete, but it's currently +// being defined where this is called. This causes an error diagnostic at the +// call. +// +// TODO: Define the function to `return U` once we can write `T:! Core.Copy`. +// Right now, due to #5750, facets are not seen to implement `Core.Copy`. +eval fn ReturnFacet[T:! type](U:! T) -> T; + +interface Y { let YT:! type; } + +interface Z {} + +interface X { let XZ:! Z; } +constraint W { + require impls Z; + // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE+17]]:31: error: function returns incomplete type `W` [IncompleteTypeInFunctionReturnType] + // CHECK:STDERR: require impls X where .XZ = ReturnFacet(Self); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-5]]:1: note: constraint is currently being defined [NamedConstraintIncompleteWithinDefinition] + // CHECK:STDERR: constraint W { + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-15]]:41: note: return type declared here [IncompleteReturnTypeHere] + // CHECK:STDERR: eval fn ReturnFacet[T:! type](U:! T) -> T; + // CHECK:STDERR: ^ + // CHECK:STDERR: + // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE+7]]:31: error: use of undefined generic function [MissingGenericFunctionDefinition] + // CHECK:STDERR: require impls X where .XZ = ReturnFacet(Self); + // CHECK:STDERR: ^~~~~~~~~~~ + // CHECK:STDERR: fail_incomplete_self.carbon:[[@LINE-22]]:1: note: generic function declared here [MissingGenericFunctionDefinitionHere] + // CHECK:STDERR: eval fn ReturnFacet[T:! type](U:! T) -> T; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + require impls X where .XZ = ReturnFacet(Self); +} diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index f7b6d72f3ac8..b83ba1c7da87 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -19,6 +19,7 @@ #include "toolchain/sem_ir/facet_type_info.h" #include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/named_constraint.h" #include "toolchain/sem_ir/specific_interface.h" #include "toolchain/sem_ir/specific_named_constraint.h" #include "toolchain/sem_ir/type_info.h" @@ -855,17 +856,6 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, return false; } -// Require all named constraints in the facet type are identified. For a named -// constraint, this means the constraint definition is complete. -static auto RequireCompleteNamedConstraint( - Context& context, SemIR::LocId loc_id, - SemIR::NamedConstraintId constraint_id, SemIR::SpecificId specific_id, - bool diagnose) -> bool { - auto facet_type = - FacetTypeFromNamedConstraint(context, constraint_id, specific_id); - return RequireCompleteFacetType(context, loc_id, facet_type, diagnose); -} - // Given a canonical facet value, or a type value, return a facet value. static auto GetSelfFacetValue(Context& context, SemIR::ConstantId self_const_id) -> SemIR::ConstantId { @@ -885,14 +875,18 @@ static auto GetSelfFacetValue(Context& context, SemIR::ConstantId self_const_id) context, context.types().GetAsTypeInstId(self_inst_id)); } -auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId self_const_id, - const SemIR::FacetType& facet_type, - DiagnosticContextFn diagnostic_context) +static auto IdentifyFacetType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId self_const_id, + const SemIR::FacetType& facet_type, + bool allow_partially_identified, bool diagnose) -> SemIR::IdentifiedFacetTypeId { - CARBON_CHECK(diagnostic_context); - Diagnostics::ContextScope scope(&context.emitter(), diagnostic_context); - + // While partially identified facet types end up in the store of + // IdentifiedFacetTypes, we don't try to construct a key to look for them + // here, so we will only early-out here for fully identified facet types. To + // construct the key for a partially identified facet type we need to know the + // set of required impls that it contains, which requires us to do most of the + // work of identifying the facet type (though we could skip the mapping of + // constant values into specifics). auto key = SemIR::IdentifiedFacetTypeKey{.facet_type_id = facet_type.facet_type_id, .self_const_id = self_const_id}; @@ -912,6 +906,7 @@ auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, {true, self_const_id, facet_type.facet_type_id}}; // Outputs for the IdentifiedFacetType. + bool partially_identified = false; llvm::SmallVector extends; llvm::SmallVector impls; @@ -945,19 +940,6 @@ auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, continue; } - // References to a named constraint require the constraint to be complete so - // that we can enumerate all the required interfaces within. - for (auto specific_constraint : - llvm::concat( - facet_type_info.extend_named_constraints, - facet_type_info.self_impls_named_constraints)) { - if (!RequireCompleteNamedConstraint( - context, loc_id, specific_constraint.named_constraint_id, - specific_constraint.specific_id, true)) { - return SemIR::IdentifiedFacetTypeId::None; - } - } - // The self may have type TypeType. But the `Self` in a generic require decl // has type FacetType, so we need something similar to replace it in the // specific. @@ -966,12 +948,35 @@ auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, for (auto extends : facet_type_info.extend_named_constraints) { const auto& constraint = context.named_constraints().Get(extends.named_constraint_id); + + llvm::ArrayRef require_impls_ids; + if (constraint.is_complete()) { + require_impls_ids = context.require_impls_blocks().Get( + constraint.require_impls_block_id); + } else if (allow_partially_identified) { + partially_identified = true; + if (constraint.is_being_defined()) { + require_impls_ids = context.require_impls_stack().PeekForScope( + extends.named_constraint_id); + } else { + continue; + } + } else { + if (diagnose) { + DiagnoseIncompleteNamedConstraint(context, + extends.named_constraint_id); + } + return SemIR::IdentifiedFacetTypeId::None; + } + auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf( context, loc_id, constraint.generic_id, constraint.generic_with_self_id, extends.specific_id, self_facet); + if (SpecificContainsError(context, constraint_with_self_specific_id)) { + return SemIR::IdentifiedFacetTypeId::None; + } - for (auto require_impls_id : context.require_impls_blocks().Get( - constraint.require_impls_block_id)) { + for (auto require_impls_id : llvm::reverse(require_impls_ids)) { const auto& require = context.require_impls().Get(require_impls_id); // Each require is in its own generic, with no additional bindings and @@ -1003,12 +1008,34 @@ auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, for (auto impls : facet_type_info.self_impls_named_constraints) { const auto& constraint = context.named_constraints().Get(impls.named_constraint_id); + + llvm::ArrayRef require_impls_ids; + if (constraint.is_complete()) { + require_impls_ids = context.require_impls_blocks().Get( + constraint.require_impls_block_id); + } else if (allow_partially_identified) { + partially_identified = true; + if (constraint.is_being_defined()) { + require_impls_ids = context.require_impls_stack().PeekForScope( + impls.named_constraint_id); + } else { + continue; + } + } else { + if (diagnose) { + DiagnoseIncompleteNamedConstraint(context, impls.named_constraint_id); + } + return SemIR::IdentifiedFacetTypeId::None; + } + auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf( context, loc_id, constraint.generic_id, constraint.generic_with_self_id, impls.specific_id, self_facet); + if (SpecificContainsError(context, constraint_with_self_specific_id)) { + return SemIR::IdentifiedFacetTypeId::None; + } - for (auto require_impls_id : context.require_impls_blocks().Get( - constraint.require_impls_block_id)) { + for (auto require_impls_id : llvm::reverse(require_impls_ids)) { const auto& require = context.require_impls().Get(require_impls_id); // Each require is in its own generic, with no additional bindings and @@ -1038,7 +1065,29 @@ auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, } // TODO: Process other kinds of requirements. - return context.identified_facet_types().Add({key, extends, impls}); + return context.identified_facet_types().Add( + {key, partially_identified, extends, impls}); +} + +auto TryToIdentifyFacetType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId self_const_id, + const SemIR::FacetType& facet_type, + bool allow_partially_identified) + -> SemIR::IdentifiedFacetTypeId { + return IdentifyFacetType(context, loc_id, self_const_id, facet_type, + allow_partially_identified, /*diagnose=*/false); +} + +auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId self_const_id, + const SemIR::FacetType& facet_type, + DiagnosticContextFn diagnostic_context, + bool diagnose) -> SemIR::IdentifiedFacetTypeId { + CARBON_CHECK(diagnostic_context); + Diagnostics::ContextScope scope(&context.emitter(), diagnostic_context); + + return IdentifyFacetType(context, loc_id, self_const_id, facet_type, + /*allow_partially_identified=*/false, diagnose); } } // namespace Carbon::Check diff --git a/toolchain/check/type_completion.h b/toolchain/check/type_completion.h index 6f692bbb3674..ddf9220807cb 100644 --- a/toolchain/check/type_completion.h +++ b/toolchain/check/type_completion.h @@ -69,6 +69,18 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, DiagnosticContextFn concrete_type_diagnostic_context) -> bool; +// Performs `RequireIdentifiedFacetType`, but it is not an error if the facet +// type is not identified. +// +// If `allow_partially_identified` is true, the facet type may be partially +// identified, which can contain interfaces from a named constraint that is in +// the middle of being defined. +auto TryToIdentifyFacetType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId self_const_id, + const SemIR::FacetType& facet_type, + bool allow_partially_identified) + -> SemIR::IdentifiedFacetTypeId; + // Requires the named constraints in the facet type to be complete, so that the // set of interfaces the facet type requires is known. The `self_const_id` is a // type or facet type expression that is the self that the FacetType is @@ -81,10 +93,13 @@ auto RequireConcreteType(Context& context, SemIR::TypeId type_id, // resulting IdentifiedFacetType. Comparing the `self_const_id` against the // output self values requires the caller to also canonicalize the // `self_const_id`. +// +// TODO: Remove `diagnose` and split into `TryIdentifyFacetType`. auto RequireIdentifiedFacetType(Context& context, SemIR::LocId loc_id, SemIR::ConstantId self_const_id, const SemIR::FacetType& facet_type, - DiagnosticContextFn diagnostic_context) + DiagnosticContextFn diagnostic_context, + bool diagnose = true) -> SemIR::IdentifiedFacetTypeId; // Emits an error diagnostic explaining that a class is incomplete. diff --git a/toolchain/diagnostics/kind.def b/toolchain/diagnostics/kind.def index 591b6e51a7ee..5513a2b2a4f5 100644 --- a/toolchain/diagnostics/kind.def +++ b/toolchain/diagnostics/kind.def @@ -372,7 +372,6 @@ CARBON_DIAGNOSTIC_KIND(MissingImplInMemberAccessInContext) CARBON_DIAGNOSTIC_KIND(ImplLookupCycle) CARBON_DIAGNOSTIC_KIND(ImplLookupCycleNote) CARBON_DIAGNOSTIC_KIND(ImplLookupInUnidentifiedFacetType) -CARBON_DIAGNOSTIC_KIND(ImplLookupInUnidentifiedFacetTypeOfQuerySelf) // Require checking. CARBON_DIAGNOSTIC_KIND(RequireImplsExtendWithExplicitSelf) diff --git a/toolchain/lower/testdata/impl/import_facet.carbon b/toolchain/lower/testdata/impl/import_facet.carbon index 01f742352412..603e77f63867 100644 --- a/toolchain/lower/testdata/impl/import_facet.carbon +++ b/toolchain/lower/testdata/impl/import_facet.carbon @@ -85,7 +85,7 @@ fn F(d: D(i32)) -> i32* { // CHECK:STDOUT: ; ModuleID = 'd.carbon' // CHECK:STDOUT: source_filename = "d.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: @C.val.7d8.anon = internal constant {} zeroinitializer +// CHECK:STDOUT: @C.val.23a.anon = internal constant {} zeroinitializer // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define ptr @_CF.Main(ptr %d) #0 !dbg !4 { @@ -93,7 +93,7 @@ fn F(d: D(i32)) -> i32* { // CHECK:STDOUT: %.loc5_21.1.temp = alloca {}, align 8, !dbg !10 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc5_21.1.temp), !dbg !10 // CHECK:STDOUT: call void @"_CGetI.D.eb057aa32837c84e.Main:I.Main.b88d1103f417c6d4"(ptr %.loc5_21.1.temp, ptr %d), !dbg !10 -// CHECK:STDOUT: %C.GetC.call = call ptr @_CGetC.C.Main.65ad70c00874dfd2(ptr %.loc5_21.1.temp), !dbg !10 +// CHECK:STDOUT: %C.GetC.call = call ptr @_CGetC.C.Main.541f3e0ecf5901d3(ptr %.loc5_21.1.temp), !dbg !10 // CHECK:STDOUT: ret ptr %C.GetC.call, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -102,12 +102,12 @@ fn F(d: D(i32)) -> i32* { // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @"_CGetI.D.eb057aa32837c84e.Main:I.Main.b88d1103f417c6d4"(ptr sret({}) %return, ptr %self) #0 !dbg !12 { -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @C.val.7d8.anon, i64 0, i1 false), !dbg !16 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @C.val.23a.anon, i64 0, i1 false), !dbg !16 // CHECK:STDOUT: ret void, !dbg !16 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind -// CHECK:STDOUT: define linkonce_odr ptr @_CGetC.C.Main.65ad70c00874dfd2(ptr %self) #0 !dbg !17 { +// CHECK:STDOUT: define linkonce_odr ptr @_CGetC.C.Main.541f3e0ecf5901d3(ptr %self) #0 !dbg !17 { // CHECK:STDOUT: %1 = alloca ptr, align 8, !dbg !21 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %1), !dbg !21 // CHECK:STDOUT: store ptr poison, ptr %1, align 8, !dbg !21 @@ -142,7 +142,7 @@ fn F(d: D(i32)) -> i32* { // CHECK:STDOUT: !14 = !{!15} // CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !12, type: !7) // CHECK:STDOUT: !16 = !DILocation(line: 7, column: 7, scope: !12) -// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "GetC", linkageName: "_CGetC.C.Main.65ad70c00874dfd2", scope: null, file: !18, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !19) +// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "GetC", linkageName: "_CGetC.C.Main.541f3e0ecf5901d3", scope: null, file: !18, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !19) // CHECK:STDOUT: !18 = !DIFile(filename: "a.carbon", directory: "") // CHECK:STDOUT: !19 = !{!20} // CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !17, type: !7) diff --git a/toolchain/sem_ir/facet_type_info.cpp b/toolchain/sem_ir/facet_type_info.cpp index d2478dd9fcec..3e66b1fb7347 100644 --- a/toolchain/sem_ir/facet_type_info.cpp +++ b/toolchain/sem_ir/facet_type_info.cpp @@ -212,7 +212,8 @@ auto FacetTypeInfo::Print(llvm::raw_ostream& out) const -> void { } IdentifiedFacetType::IdentifiedFacetType( - IdentifiedFacetTypeKey key, llvm::ArrayRef extends, + IdentifiedFacetTypeKey key, bool partially_identified, + llvm::ArrayRef extends, llvm::ArrayRef self_impls) : key_(key) { required_impls_.reserve(extends.size() + self_impls.size()); @@ -231,6 +232,14 @@ IdentifiedFacetType::IdentifiedFacetType( llvm::append_range(required_impls_, self_impls); SortAndDeduplicate(required_impls_, RequiredLess); + + if (partially_identified) { + // This marks the IdentifiedFacetType as being partially identified, and + // prevents the key from colliding with a fully identified facet type, or + // with other partially (but differently) identified facet types, with the + // same constituents but a more complete set of required interfaces. + key_.num_require_impls = required_impls_.size(); + } } auto AddCanonicalWitnessesBlock(File& sem_ir, diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index 4484276ef6e1..8201863a7a69 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -128,6 +128,11 @@ using FacetTypeInfoStore = struct IdentifiedFacetTypeKey { FacetTypeId facet_type_id; ConstantId self_const_id; + // Inside a named constraint, each identification of the `Self` facet type can + // be unique, as it can be modified by each require declaration seen so far. + // Uses -1 for identifying a facet type with a self-type from outside the + // definition of an named constraint. + int32_t num_require_impls = -1; friend auto operator==(const IdentifiedFacetTypeKey& lhs, const IdentifiedFacetTypeKey& rhs) -> bool = default; @@ -143,7 +148,7 @@ struct IdentifiedFacetType { -> bool = default; }; - IdentifiedFacetType(IdentifiedFacetTypeKey key, + IdentifiedFacetType(IdentifiedFacetTypeKey key, bool partially_identified, llvm::ArrayRef extends, llvm::ArrayRef self_impls); @@ -175,6 +180,10 @@ struct IdentifiedFacetType { } } + auto partially_identified() const -> bool { + return key_.num_require_impls >= 0; + } + auto GetAsKey() const -> IdentifiedFacetTypeKey { return key_; } private: diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 476fbc415802..da12c52033d9 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -1189,21 +1189,16 @@ struct IntValue { IntId int_id; }; -// A symbolic instruction that takes the place of an `ImplWitness` when the -// result is not fully known. When evaluated it does an impl lookup query, based -// on the stored query arguments, that a type implements an interface. The query -// can be symbolic, and thus modified to be more concrete by applying a -// specific. Once the query is concrete enough, or a final impl is found, the -// instruction evaluates to an `ImplWitness`. +// A non-final witness representing an impl lookup that did not yet find a final +// witness. // -// This instruction also represents a promise that an impl lookup query was -// satisfied, like `ImplWitness`, but without providing which impl declaration -// satisfies it. +// When a final impl becomes available, or once the query and specific interface +// are monomorphized to be concrete, this evaluates to that final witness. struct LookupImplWitness { static constexpr auto Kind = InstKind::LookupImplWitness.Define( {.ir_name = "lookup_impl_witness", - .constant_kind = InstConstantKind::SymbolicOnly, + .constant_kind = InstConstantKind::Conditional, .constant_needs_inst_id = InstConstantNeedsInstIdKind::DuringEvaluation, .is_lowered = false});