From d6be20641c0604ae4df915439369c9674ecbda4a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 26 Mar 2026 11:26:56 -0400 Subject: [PATCH] Use earlier `require` decls inside a named constraint to provide witnesses for `Self` (#6915) Performing a lookup against `Self` inside the definition of the named constraint leads to cycles, as described in the document [Self contradictions in Named Constraints](https://docs.google.com/document/d/17rn2XmME8o2MM4OJqatSVuMa1iYZ1PAgcNrf0PXR9Q4/edit?tab=t.0). To prevent those cycles, this change introduces a large refactoring of impl lookup. The impl lookup done inside eval is reduced to only performing monomorphization. That is it: - Only looks for an provides final witnesses. - Is not allowed to identify the facet type of the query self. - Returns either a final witness or None (or an error) The paths for finding non-final witnesses are now done outside of eval, directly in the initial `LookupImplWitness()` function. If no final witness it found through eval, the resulting non-final `LookupImplWitness` instruction witness is returned. It does not produce cycles to identify the facet type of query self outside of eval, since that does not result in repeating the identification when resolving specifics of the named constraint or require decl. Move the ArrayStack for Context::require_impls_stack into a new class which tracks a NamedConstraintId (or InterfaceId) for each frame of RequireImplsIds, so that in type completion we always can find the correct frame for a given named constraint which is still being defined, in order to find the RequireImplsIds in the in-progress definition. --- toolchain/check/BUILD | 2 + toolchain/check/check_unit.cpp | 19 +- toolchain/check/context.h | 14 +- toolchain/check/convert.cpp | 2 +- toolchain/check/custom_witness.cpp | 20 +- toolchain/check/custom_witness.h | 8 +- toolchain/check/eval_inst.cpp | 55 +- toolchain/check/generic.cpp | 15 +- toolchain/check/handle_interface.cpp | 6 +- toolchain/check/handle_named_constraint.cpp | 6 +- toolchain/check/impl_lookup.cpp | 792 +++++++++++------- toolchain/check/impl_lookup.h | 74 +- toolchain/check/require_impls_stack.cpp | 36 + toolchain/check/require_impls_stack.h | 44 + .../basics/raw_sem_ir/one_file.carbon | 36 +- .../check/testdata/class/generic/basic.carbon | 4 +- .../class/generic/member_access.carbon | 6 +- .../testdata/class/generic/member_type.carbon | 6 +- .../testdata/deduce/binding_pattern.carbon | 4 + .../check/testdata/eval/aggregates.carbon | 16 +- ..._facet_value_to_narrowed_facet_type.carbon | 4 +- ...t_facet_value_value_to_blanket_impl.carbon | 4 +- ..._value_to_generic_facet_value_value.carbon | 22 +- ...convert_facet_value_to_missing_impl.carbon | 2 + .../testdata/facet/fail_incomplete.carbon | 33 - .../facet/partially_identified.carbon | 216 +++++ .../facet/require_constrains_self.carbon | 66 -- .../testdata/facet/require_invalid.carbon | 17 + toolchain/check/testdata/for/actual.carbon | 67 +- .../testdata/function/generic/call.carbon | 8 +- .../testdata/function/generic/deduce.carbon | 8 +- .../generic/indirect_generic_type.carbon | 4 +- .../function/generic/resolve_used.carbon | 6 +- .../function/generic/type_param.carbon | 4 +- .../function/generic/type_param_scope.carbon | 4 +- .../generic/dot_self_symbolic_type.carbon | 18 +- .../generic/template/unimplemented.carbon | 6 + .../generic/template_dependence.carbon | 4 +- .../check/testdata/impl/error_recovery.carbon | 10 +- .../check/testdata/impl/impl_thunk.carbon | 8 +- .../testdata/impl/import_builtin_call.carbon | 8 +- .../check/testdata/impl/import_generic.carbon | 116 +-- .../testdata/impl/import_self_specific.carbon | 54 +- .../check/testdata/impl/incomplete.carbon | 4 +- .../check/testdata/impl/lookup/generic.carbon | 6 +- .../testdata/impl/lookup/impl_forall.carbon | 10 +- ...pecialization_with_symbolic_rewrite.carbon | 14 +- .../lookup/use_impl_from_definition.carbon | 44 + .../name_lookup_in_impl_definition.carbon | 31 + .../testdata/interface/as_type_of_type.carbon | 4 +- .../interface/compound_member_access.carbon | 14 +- .../interface/fail_assoc_const_alias.carbon | 6 +- .../interface/fail_member_lookup.carbon | 3 + ..._todo_define_default_fn_out_of_line.carbon | 4 +- .../check/testdata/interface/generic.carbon | 2 + .../testdata/interface/generic_method.carbon | 6 +- .../testdata/interface/member_lookup.carbon | 4 +- .../named_constraint/empty_generic.carbon | 10 +- .../named_constraint/incomplete.carbon | 115 ++- toolchain/check/type_completion.cpp | 121 ++- toolchain/check/type_completion.h | 17 +- toolchain/diagnostics/kind.def | 1 - .../lower/testdata/impl/import_facet.carbon | 10 +- toolchain/sem_ir/facet_type_info.cpp | 11 +- toolchain/sem_ir/facet_type_info.h | 11 +- toolchain/sem_ir/typed_insts.h | 15 +- 66 files changed, 1429 insertions(+), 888 deletions(-) create mode 100644 toolchain/check/require_impls_stack.cpp create mode 100644 toolchain/check/require_impls_stack.h delete mode 100644 toolchain/check/testdata/facet/fail_incomplete.carbon create mode 100644 toolchain/check/testdata/facet/partially_identified.carbon delete mode 100644 toolchain/check/testdata/facet/require_constrains_self.carbon create mode 100644 toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon create mode 100644 toolchain/check/testdata/impl/name_lookup_in_impl_definition.carbon 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});