From e87e5dc08d9f19101f36f2869a461983c02ecd23 Mon Sep 17 00:00:00 2001 From: danakj Date: Thu, 27 Feb 2025 18:07:10 -0500 Subject: [PATCH 01/21] Support impl lookup for multiple interfaces in a facet type If the query facet type has more than one interface, we must find an impl that provides that interface for the query type for each interface. This just looks like a for loop over the interfaces and ensuring we found one impl witness for every one. However the impl matching must change since it can't look at the constant value of the entire query facet type for comparison with the impl, as that query facet type may be for multiple interfaces and we are looking to match an impl of a single interface. To do this we break the query facet type up into each interface and make sure the interface ids match. Then ensure that the impl was able to deduce any generic parameters using the specific of the single query interface. There are some TODOs left here: 1. If the facet type for the query or the impl constraint has "other_requirements" then we can't verify that they match since they are lost. We fall back to comparing the constant id of the query to the impl's constraint (after deducing generics in the impl). This correctly eliminates mismatches but eagerly eliminates impls that could match the query interface as well when there's more than one interface in the query. 2. We don't return a witness for every interface in the query facet type. Since we can't demonstrate any use of the witness there yet, for cases that can have more than one interface in the query facet type, this doesn't break anything that was previously working. The return value is currently treated as a bool for cases with multiple interfaces in the facet type (as a test for "can this be converted") but the converted-to facet value's witnesses are unused. --- toolchain/check/deduce.cpp | 8 +- toolchain/check/deduce.h | 3 +- toolchain/check/impl_lookup.cpp | 210 ++++++++---- .../testdata/facet/no_prelude/combine.carbon | 199 ++++++++--- .../impl/fail_todo_use_assoc_const.carbon | 309 ++++++++++++++++-- .../impl/no_prelude/impl_cycle.carbon | 15 + toolchain/sem_ir/constant.h | 7 - 7 files changed, 614 insertions(+), 137 deletions(-) diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index 5040f544c2bc0..57da397333261 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -639,11 +639,10 @@ auto DeduceGenericCallArguments( return deduction.MakeSpecific(); } -// Deduces the impl arguments to use in a use of a parameterized impl. Returns -// `None` if deduction fails. auto DeduceImplArguments(Context& context, SemIR::LocId loc_id, const SemIR::Impl& impl, SemIR::ConstantId self_id, - SemIR::ConstantId constraint_id) -> SemIR::SpecificId { + SemIR::SpecificId constraint_specific_id) + -> SemIR::SpecificId { DeductionContext deduction(context, loc_id, impl.generic_id, /*enclosing_specific_id=*/SemIR::SpecificId::None, /*self_type_id=*/SemIR::InstId::None, @@ -652,8 +651,7 @@ auto DeduceImplArguments(Context& context, SemIR::LocId loc_id, // Prepare to perform deduction of the type and interface. deduction.Add(impl.self_id, context.constant_values().GetInstId(self_id), /*needs_substitution=*/false); - deduction.Add(impl.constraint_id, - context.constant_values().GetInstId(constraint_id), + deduction.Add(impl.interface.specific_id, constraint_specific_id, /*needs_substitution=*/false); if (!deduction.Deduce() || !deduction.CheckDeductionIsComplete()) { diff --git a/toolchain/check/deduce.h b/toolchain/check/deduce.h index d4d4321882bd4..778ce734973e9 100644 --- a/toolchain/check/deduce.h +++ b/toolchain/check/deduce.h @@ -22,7 +22,8 @@ auto DeduceGenericCallArguments( // `None` if deduction fails. auto DeduceImplArguments(Context& context, SemIR::LocId loc_id, const SemIR::Impl& impl, SemIR::ConstantId self_id, - SemIR::ConstantId constraint_id) -> SemIR::SpecificId; + SemIR::SpecificId constraint_specific_id) + -> SemIR::SpecificId; } // namespace Carbon::Check diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 8b077c5bbeebf..c5f88b5d0f492 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -157,14 +157,12 @@ static auto FindAndDiagnoseImplLookupCycle( return false; } -// Gets the `SemIR::InterfaceId` for a facet type (as a constant value). -// -// The facet type requires only one `InterfaceId` right now. But in the future, -// a facet type may include more than a single interface. For now that is -// unhandled with a TODO. -static auto GetInterfaceIdFromConstantId(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId interface_const_id) - -> SemIR::InterfaceId { +// Gets the set of `SemIR::InterfaceId`s that are available given a facet type +// (as a constant value). +static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId interface_const_id) + -> llvm::SmallVector< + std::pair, 16> { // The `interface_const_id` is a constant value for some facet type. We do // this long chain of steps to go from that constant value to the // `FacetTypeId` found on the `FacetType` instruction of this constant value, @@ -183,6 +181,10 @@ static auto GetInterfaceIdFromConstantId(Context& context, SemIR::LocId loc_id, const auto& complete_facet_type = context.complete_facet_types().Get(complete_facet_type_id); + llvm::SmallVector< + std::pair, 16> + interface_ids; + if (complete_facet_type.required_interfaces.empty()) { // This should never happen - a FacetType either requires or is bounded by // some `.Self impls` clause. Otherwise you would just have `type` (aka @@ -190,72 +192,123 @@ static auto GetInterfaceIdFromConstantId(Context& context, SemIR::LocId loc_id, context.TODO(loc_id, "impl lookup for a FacetType with no interface (using " "`where .Self impls ...` instead?)"); - return SemIR::InterfaceId::None; + return interface_ids; } - if (complete_facet_type.required_interfaces.size() > 1) { - context.TODO(loc_id, - "impl lookup for a FacetType with more than one interface"); - return SemIR::InterfaceId::None; + for (auto required : complete_facet_type.required_interfaces) { + interface_ids.push_back( + {required, + context.facet_types().Get(facet_type_id).other_requirements}); } - return complete_facet_type.required_interfaces[0].interface_id; + return interface_ids; } -static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId type_const_id, - SemIR::ConstantId interface_const_id, - SemIR::InterfaceId interface_id, - const SemIR::Impl& impl) -> SemIR::InstId { - // If impl.constraint_id is not symbolic, and doesn't match the query, then - // we don't need to proceed. - auto impl_interface_const_id = - context.constant_values().Get(impl.constraint_id); - if (!impl_interface_const_id.is_symbolic() && - interface_const_id != impl_interface_const_id) { - return SemIR::InstId::None; - } - - // This is the (single) interface named in the query `interface_const_id`. +static auto GetWitnessIdForImpl( + Context& context, SemIR::LocId loc_id, SemIR::ConstantId type_const_id, + SemIR::ConstantId interface_const_id, + const SemIR::CompleteFacetType::RequiredInterface& interface, + bool interface_has_other_requirements, const SemIR::Impl& impl) + -> SemIR::InstId { // If the impl's interface_id differs from the query, then this impl can not // possibly provide the queried interface, and we don't need to proceed. - // Unlike the early-out above comparing the `impl.constraint_id`, this also - // elides looking at impls of generic interfaces where the interface itself - // does not match the query. - if (impl.interface.interface_id != interface_id) { + if (impl.interface.interface_id != interface.interface_id) { return SemIR::InstId::None; } - auto specific_id = SemIR::SpecificId::None; + // impl C as A where .Self impls I {} + + // ({} as C) as (C as (A & B)) + // ^ FacetValue witnesses for A and B + // ^ CompleteFacetType has 2 required_interfaces + + // When the impl's interface_id matches, but the interface is generic, the + // impl may or may not match based on restrictions in the generic parameters + // of the impl. + // + // As a shortcut, if the impl's constraint is not symbolic (does not depend on + // any generic parameters), then we can determine if we match if the specific + // ids match exactly. + auto impl_interface_const_id = + context.constant_values().Get(impl.constraint_id); + if (!impl_interface_const_id.is_symbolic()) { + if (impl.interface.specific_id != interface.specific_id) { + return SemIR::InstId::None; + } + } + // This check comes first to avoid deduction with an invalid impl. We use an // error value to indicate an error during creation of the impl, such as a // recursive impl which will cause deduction to recurse infinitely. if (impl.witness_id == SemIR::ErrorInst::SingletonInstId) { return SemIR::InstId::None; } + if (!impl.witness_id.has_value()) { + // TODO: Diagnose if the impl isn't defined yet? + return SemIR::InstId::None; + } + + // The impl may have generic arguments, in which case we need to deduce them + // to find what they are given the specific interface query. We use that + // specific to map values in the impl to the deduced values. + auto specific_id = SemIR::SpecificId::None; if (impl.generic_id.has_value()) { specific_id = DeduceImplArguments(context, loc_id, impl, type_const_id, - interface_const_id); + interface.specific_id); if (!specific_id.has_value()) { return SemIR::InstId::None; } } - if (!context.constant_values().AreEqualAcrossDeclarations( - SemIR::GetConstantValueInSpecific(context.sem_ir(), specific_id, - impl.self_id), - type_const_id)) { + + // The self type of the impl must match the type in the query, or this is an + // `impl T as ...` for some other type `T` and should not be considered. + auto deduced_self_const_id = SemIR::GetConstantValueInSpecific( + context.sem_ir(), specific_id, impl.self_id); + if (type_const_id != deduced_self_const_id) { return SemIR::InstId::None; } - if (!context.constant_values().AreEqualAcrossDeclarations( - SemIR::GetConstantValueInSpecific(context.sem_ir(), specific_id, - impl.constraint_id), - interface_const_id)) { - // TODO: An impl of a constraint type should be treated as implementing - // the constraint's interfaces. + + // The impl's constraint is a facet type which it is implementing for the self + // type: the `I` in `impl ... as I`. The deduction step may be unable to be + // fully applied to the types in the constraint and result in an error here, + // in which case it does not match the query. + auto deduced_constraint_id = + context.constant_values().GetInstId(SemIR::GetConstantValueInSpecific( + context.sem_ir(), specific_id, impl.constraint_id)); + if (deduced_constraint_id == SemIR::ErrorInst::SingletonInstId) { return SemIR::InstId::None; } - if (!impl.witness_id.has_value()) { - // TODO: Diagnose if the impl isn't defined yet? - return SemIR::InstId::None; + + auto deduced_constaint_facet_type_id = + context.insts() + .GetAs(deduced_constraint_id) + .facet_type_id; + bool constraint_has_other_requirements = + context.facet_types() + .Get(deduced_constaint_facet_type_id) + .other_requirements; + + // If there are requirements on the impl's constraint facet type, or on the + // query facet type, that are not modelled yet in the FacetTypeInfo and + // CompleteFacetType, then we can't tell if we have a match for this specific + // query interface. + // + // In this case we just do the wrong thing if the either the constraint or + // query facet type had more than one interface in it, and compare the + // constant value of the entire query facet type against the entire impl's + // constraint facet type. The latter will include those other requirements + // (correctly), but the former may include more things unrelated to this one + // interface being looked for here and thus fail incorrectly. + // + // TODO: Stop using `other_requirements` and look at `where .Self impls` + // clauses with further impl lookups as needed. These should become part of + // the set of interfaces for which this function is called on, and this + // function shouldn't have to think about them. + if (constraint_has_other_requirements || interface_has_other_requirements) { + if (context.constant_values().Get(deduced_constraint_id) != + interface_const_id) { + return SemIR::InstId::None; + } } + LoadImportRef(context, impl.witness_id); if (specific_id.has_value()) { // We need a definition of the specific `impl` so we can access its @@ -292,28 +345,69 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, return SemIR::ErrorInst::SingletonInstId; } - auto interface_id = - GetInterfaceIdFromConstantId(context, loc_id, interface_const_id); + auto interfaces = + GetInterfacesFromConstantId(context, loc_id, interface_const_id); + if (interfaces.empty()) { + // TODO: Remove this when the context.TODO() is removed in + // GetInterfaceIdsFromConstantId. + return SemIR::InstId::None; + } - auto result_witness_id = SemIR::InstId::None; + llvm::SmallVector result_witness_ids; auto& stack = context.impl_lookup_stack(); stack.push_back({ .type_const_id = type_const_id, .interface_const_id = interface_const_id, }); - for (const auto& impl : context.impls().array_ref()) { - stack.back().impl_loc = impl.definition_id; - result_witness_id = GetWitnessIdForImpl( - context, loc_id, type_const_id, interface_const_id, interface_id, impl); - if (result_witness_id.has_value()) { - // We found a matching impl, don't keep looking. + // We need to find a witness for each interface in `interface_ids`. We return + // them in the same order as they are found in the `CompleteFacetType`, which + // is the same order as in `interface_ids` here. + for (const auto& [interface, interface_has_other_requirements] : interfaces) { + bool found_witness = false; + for (const auto& impl : context.impls().array_ref()) { + stack.back().impl_loc = impl.definition_id; + auto result_witness_id = GetWitnessIdForImpl( + context, loc_id, type_const_id, interface_const_id, interface, + interface_has_other_requirements, impl); + if (result_witness_id.has_value()) { + result_witness_ids.push_back(result_witness_id); + // We found a matching impl; don't keep looking for this `interface_id`, + // move onto the next. + found_witness = true; + break; + } + } + if (!found_witness) { + // 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(); - return result_witness_id; + // All interfaces in the query facet type must have been found to be available + // through some impl (TODO: or directly on the type itself if `type_const_id` + // is a facet type). + if (result_witness_ids.size() != interfaces.size()) { + return SemIR::InstId::None; + } + + // TODO: Return the whole set as a (newly introduced) FacetTypeWitness + // instruction. For now we just return a single witness instruction which + // doesn't matter because it essentially goes unused anyway. So far this + // method is just used as a boolean test in cases where there can be more than + // one interface in the query facet type: + // - Concrete facet values (`({} as C) as (C as (A & B))`) are looked through + // to the implementing type (typically a ClassType) to access members, and + // thus don't use the witnesses in the facet value. + // - Compound member lookup (`G.(A & B).F()`) uses name lookup to find the + // interface first, then does impl lookup for a witness with a single + // interface query. It's also only possible on concrete facet values so far + // (see below). + // - Qualified name lookup on symbolic facet values (`T:! A & B`) doesn't work + // at all, so never gets to looking for a witness. + return result_witness_ids[0]; } } // namespace Carbon::Check diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon index 466a859134a25..c369ec17d5bbe 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine.carbon +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -109,7 +109,7 @@ fn F() { ({} as C).((A & B).G)(); } -// --- fail_todo_combine.carbon +// --- combine.carbon library "[[@TEST_NAME]]"; import Core; @@ -128,76 +128,185 @@ impl C as B { fn F() { ({} as C).((A & B).G)(); - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+11]]:18: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A & B` with `as` [ExplicitAsConversionFailure] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A & B)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: (({} as C) as (C as (A & B))).((A & B).G)(); - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+11]]:18: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A & B` with `as` [ExplicitAsConversionFailure] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_combine.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A & B)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); - // CHECK:STDERR: ^~~~~~~~~~~~ - // CHECK:STDERR: (({} as C) as (C as (A & B))).((B).G)(); } -// --- fail_todo_generic_combine.carbon +// --- fail_todo_generic_param_is_combined.carbon library "[[@TEST_NAME]]"; import Core; interface A { + fn G(); } interface B { - fn G(); + fn H(); } fn G[T:! A & B](t: T) { - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] - // CHECK:STDERR: t.(B.G)(); - // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: fail_todo_generic_param_is_combined.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: t.G(); + // CHECK:STDERR: ^~~ // CHECK:STDERR: - t.(B.G)(); + t.G(); + // CHECK:STDERR: fail_todo_generic_param_is_combined.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: t.H(); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + t.H(); } class C {} -impl C as A {} +impl C as A { + fn G() {} +} +impl C as B { + fn H() {} +} + +fn F() { + G({} as C); +} + +// --- todo_generic_interface.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A(T:! type) {} +interface B { + fn G(); +} + +class P1 {} +class P2 {} + +class C {} +impl C as A(P1) {} +impl C as B { + fn G() {} +} + +fn F() { + // TODO: Qualified lookup of `G` should not be needed here. + (({} as C) as (C as (A(P1) & B))).(B.G)(); +} + +// --- fail_wrong_generic_interface.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A(T:! type) {} +interface B { + fn G(); +} + +class P1 {} +class P2 {} + +class C {} +impl C as A(P1) {} impl C as B { fn G() {} } fn F() { - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+17]]:3: error: semantics TODO: `impl lookup for a FacetType with more than one interface` [SemanticsTodo] - // CHECK:STDERR: G({} as C); - // CHECK:STDERR: ^~~~~~~~~~ - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE-18]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: fn G[T:! A & B](t: T) { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A(P2) & B` with `as` [ExplicitAsConversionFailure] + // CHECK:STDERR: (({} as C) as (C as (A(P2) & B))).(B.G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A(P2) & B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: (({} as C) as (C as (A(P2) & B))).(B.G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+10]]:3: error: cannot implicitly convert from `type` to `A & B` [ImplicitAsConversionFailure] - // CHECK:STDERR: G({} as C); - // CHECK:STDERR: ^~~~~~~~~~ - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(A & B)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: G({} as C); - // CHECK:STDERR: ^~~~~~~~~~ - // CHECK:STDERR: fail_todo_generic_combine.carbon:[[@LINE-28]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] - // CHECK:STDERR: fn G[T:! A & B](t: T) { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ + (({} as C) as (C as (A(P2) & B))).(B.G)(); +} + +// --- todo_generic_interface_parameter.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface A { + fn AA(); +} +interface B { + fn BB(); +} + +class C {} +impl C as A { + fn AA() {} +} +impl C as B { + fn BB() {} +} + +fn G[T:! A & B](t: T) { + // TODO: Lookup of `AA` and `BB` should be possible here, using the witnesses + // found in type deduction. + + // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: t.AA(); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: + t.AA(); + // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: t.BB(); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: + t.BB(); + + // TODO: Qualified lookup of `AA` and `BB` should also be possible here, using + // the witnesses found in type deduction. + + // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `T` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: t.(A.AA)(); + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + t.(A.AA)(); + // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: t.(B.BB)(); + // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: + t.(B.BB)(); +} + +fn F() { G({} as C); } + + +// --- todo_generic_forall_impl.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface Iface { fn Q(); } +interface GenericIface(T:! type) { fn R(); } + +class GenericClass(T:! type) {} + +class C {} +impl C as Iface { fn Q() {} } + +impl forall [IfaceType:! Iface] C as GenericIface(GenericClass(IfaceType)) { + fn R() {} +} + +class ImplIface {} +impl ImplIface as Iface { fn Q() {} } + +fn F() { + ({} as C) as (C as Iface); + ({} as C) as (C as GenericIface(GenericClass(ImplIface))); + + ({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface)))); + + // TODO: Qualified lookup of `Q` and `R` should not be needed here. + (({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface))))).(Iface.Q)(); + (({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface))))).(GenericIface(GenericClass(ImplIface)).R)(); +} diff --git a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon index effa4190de375..c4abc53baa794 100644 --- a/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/fail_todo_use_assoc_const.carbon @@ -43,7 +43,7 @@ impl C as J where .U = C { fn F[self: Self](u: C) -> C { return self; } } -// --- fail_todo_use_non-type_in_function.carbon +// --- use_non-type_in_function.carbon library "[[@TEST_NAME]]"; interface M { @@ -53,13 +53,29 @@ interface M { impl () as M where .Z = {.b = {}} { fn G() -> {} { - // CHECK:STDERR: fail_todo_use_non-type_in_function.carbon:[[@LINE+7]]:13: error: cannot convert from `type` to `M` with `as` [ExplicitAsConversionFailure] - // CHECK:STDERR: return (Self as M).Z.b; - // CHECK:STDERR: ^~~~~~~~~ - // CHECK:STDERR: fail_todo_use_non-type_in_function.carbon:[[@LINE+4]]:13: note: type `type` does not implement interface `Core.As(M)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: return (Self as M).Z.b; - // CHECK:STDERR: ^~~~~~~~~ - // CHECK:STDERR: + return (Self as M).Z.b; + } +} + +// --- self_as_uses_correct_rewrite_constraint.carbon + +library "[[@TEST_NAME]]"; + +class C(T:! type) {} + +interface M { + let Z:! {.b: type}; + fn G() -> type; +} + +impl C({}) as M where .Z = {.b = {}} { + fn G() -> type { + return (Self as M).Z.b; + } +} + +impl C(()) as M where .Z = {.b = ()} { + fn G() -> type { return (Self as M).Z.b; } } @@ -316,16 +332,16 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %Self.as_type.loc19_14.1 => constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_use_non-type_in_function.carbon +// CHECK:STDOUT: --- use_non-type_in_function.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %M.type: type = facet_type <@M> [concrete] -// CHECK:STDOUT: %Self.bcc: %M.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %struct_type.b.347: type = struct_type {.b: %empty_struct_type} [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %M.assoc_type: type = assoc_entity_type %M.type [concrete] -// CHECK:STDOUT: %assoc0.e3d: %M.assoc_type = assoc_entity element0, @M.%Z [concrete] +// CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete] // CHECK:STDOUT: %G.type.020: type = fn_type @G.1 [concrete] // CHECK:STDOUT: %G.91c: %G.type.020 = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %M.assoc_type = assoc_entity element1, @M.%G.decl [concrete] @@ -345,7 +361,6 @@ impl () as I where .N = 2 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .As = %Core.As // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -364,7 +379,7 @@ impl () as I where .N = 2 { // CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] // CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0.e3d] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic_self = constants.%.Self.as_wit] @@ -383,9 +398,9 @@ impl () as I where .N = 2 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @M { -// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.bcc] +// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %Z: %struct_type.b.347 = assoc_const_decl @Z [concrete] { -// CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete = constants.%assoc0.e3d] +// CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete = constants.%assoc0] // CHECK:STDOUT: } // CHECK:STDOUT: %G.decl: %G.type.020 = fn_decl @G.1 [concrete = constants.%G.91c] { // CHECK:STDOUT: %return.patt: %empty_struct_type = return_slot_pattern @@ -434,20 +449,272 @@ impl () as I where .N = 2 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.%.loc8_7.2 [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] -// CHECK:STDOUT: %.loc17: %M.type = converted %Self.ref, [concrete = ] -// CHECK:STDOUT: %Z.ref: = name_ref Z, [concrete = ] -// CHECK:STDOUT: %b.ref: = name_ref b, [concrete = ] -// CHECK:STDOUT: return +// CHECK:STDOUT: %M.facet: %M.type = facet_value constants.%empty_tuple.type, constants.%impl_witness [concrete = constants.%M.facet.940] +// CHECK:STDOUT: %.loc10_18: %M.type = converted %Self.ref, %M.facet [concrete = constants.%M.facet.940] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %as_type: type = facet_access_type %.loc10_18 [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc10_23: type = converted %.loc10_18, %as_type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %as_wit: = facet_access_witness %.loc10_18 [concrete = constants.%impl_witness] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.347 = impl_witness_access %as_wit, element0 [concrete = constants.%struct] +// CHECK:STDOUT: %.loc10_25: %empty_struct_type = struct_access %impl.elem0, element0 [concrete = constants.%empty_struct] +// CHECK:STDOUT: return %.loc10_25 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Z(constants.%Self.bcc) {} +// CHECK:STDOUT: specific @Z(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @G.1(constants.%Self.bcc) {} +// CHECK:STDOUT: specific @G.1(constants.%Self) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Z(constants.%M.facet.ba5) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @G.1(constants.%M.facet.940) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%M.facet.940) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- self_as_uses_correct_rewrite_constraint.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %M.type: type = facet_type <@M> [concrete] +// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %struct_type.b.86f: type = struct_type {.b: type} [concrete] +// CHECK:STDOUT: %M.assoc_type: type = assoc_entity_type %M.type [concrete] +// CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete] +// CHECK:STDOUT: %G.type.020: type = fn_type @G.1 [concrete] +// CHECK:STDOUT: %G.91c: %G.type.020 = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %M.assoc_type = assoc_entity element1, @M.%G.decl [concrete] +// CHECK:STDOUT: %C.7a7: type = class_type @C, @C(%empty_struct_type) [concrete] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self [symbolic_self] +// CHECK:STDOUT: %M.facet.ba5: %M.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic_self] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.86f = impl_witness_access %.Self.as_wit, element0 [symbolic_self] +// CHECK:STDOUT: %struct_type.b.347: type = struct_type {.b: %empty_struct_type} [concrete] +// CHECK:STDOUT: %struct.0f3: %struct_type.b.86f = struct_value (%empty_struct_type) [concrete] +// CHECK:STDOUT: %M_where.type.fd0: type = facet_type <@M where %impl.elem0 = %struct.0f3> [concrete] +// CHECK:STDOUT: %impl_witness.046: = impl_witness (%struct.0f3, @impl.b80.%G.decl) [concrete] +// CHECK:STDOUT: %G.type.bce: type = fn_type @G.2 [concrete] +// CHECK:STDOUT: %G.8af: %G.type.bce = struct_value () [concrete] +// CHECK:STDOUT: %M.facet.f90: %M.type = facet_value %C.7a7, %impl_witness.046 [concrete] +// CHECK:STDOUT: %C.3a0: type = class_type @C, @C(%empty_tuple.type) [concrete] +// CHECK:STDOUT: %struct_type.b.161: type = struct_type {.b: %empty_tuple.type} [concrete] +// CHECK:STDOUT: %struct.c94: %struct_type.b.86f = struct_value (%empty_tuple.type) [concrete] +// CHECK:STDOUT: %M_where.type.b49: type = facet_type <@M where %impl.elem0 = %struct.c94> [concrete] +// CHECK:STDOUT: %impl_witness.e37: = impl_witness (%struct.c94, @impl.be1.%G.decl) [concrete] +// CHECK:STDOUT: %G.type.875: type = fn_type @G.3 [concrete] +// CHECK:STDOUT: %G.702: %G.type.875 = struct_value () [concrete] +// CHECK:STDOUT: %M.facet.2a4: %M.type = facet_value %C.3a0, %impl_witness.e37 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .M = %M.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { +// CHECK:STDOUT: %T.patt.loc4_9.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc4_9.1, runtime_param [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %M.decl: type = interface_decl @M [concrete = constants.%M.type] {} {} +// CHECK:STDOUT: impl_decl @impl.b80 [concrete] {} { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] +// CHECK:STDOUT: %.loc11_9: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_10: type = converted %.loc11_9, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%empty_struct_type) [concrete = constants.%C.7a7] +// CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc11_23: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic_self = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.86f = impl_witness_access %.Self.as_wit, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %.loc11_35: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_36.1: %struct_type.b.347 = struct_literal (%.loc11_35) +// CHECK:STDOUT: %.loc11_36.2: type = converted %.loc11_35, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %struct: %struct_type.b.86f = struct_value (%.loc11_36.2) [concrete = constants.%struct.0f3] +// CHECK:STDOUT: %.loc11_36.3: %struct_type.b.86f = converted %.loc11_36.1, %struct [concrete = constants.%struct.0f3] +// CHECK:STDOUT: %.loc11_17: type = where_expr %.Self [concrete = constants.%M_where.type.fd0] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc11_36.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc11: = impl_witness (constants.%struct.0f3, @impl.b80.%G.decl) [concrete = constants.%impl_witness.046] +// CHECK:STDOUT: impl_decl @impl.be1 [concrete] {} { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] +// CHECK:STDOUT: %.loc17_9: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc17_10: type = converted %.loc17_9, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%empty_tuple.type) [concrete = constants.%C.3a0] +// CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] +// CHECK:STDOUT: %.Self: %M.type = bind_symbolic_name .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %M.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc17_23: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic_self = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.86f = impl_witness_access %.Self.as_wit, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %.loc17_35: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc17_36.1: %struct_type.b.161 = struct_literal (%.loc17_35) +// CHECK:STDOUT: %.loc17_36.2: type = converted %.loc17_35, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %struct: %struct_type.b.86f = struct_value (%.loc17_36.2) [concrete = constants.%struct.c94] +// CHECK:STDOUT: %.loc17_36.3: %struct_type.b.86f = converted %.loc17_36.1, %struct [concrete = constants.%struct.c94] +// CHECK:STDOUT: %.loc17_17: type = where_expr %.Self [concrete = constants.%M_where.type.b49] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc17_36.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (constants.%struct.c94, @impl.be1.%G.decl) [concrete = constants.%impl_witness.e37] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @M { +// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Z: %struct_type.b.86f = assoc_const_decl @Z [concrete] { +// CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete = constants.%assoc0] +// CHECK:STDOUT: } +// CHECK:STDOUT: %G.decl: %G.type.020 = fn_decl @G.1 [concrete = constants.%G.91c] { +// CHECK:STDOUT: %return.patt: type = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: type = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %return.param: ref type = out_param runtime_param0 +// CHECK:STDOUT: %return: ref type = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc1: %M.assoc_type = assoc_entity element1, %G.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Z = @Z.%assoc0 +// CHECK:STDOUT: .G = %assoc1 +// CHECK:STDOUT: witness = (%Z, %G.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic assoc_const @Z(@M.%Self: %M.type) { +// CHECK:STDOUT: assoc_const Z:! %struct_type.b.86f; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.b80: %C as %.loc11_17 { +// CHECK:STDOUT: %G.decl: %G.type.bce = fn_decl @G.2 [concrete = constants.%G.8af] { +// CHECK:STDOUT: %return.patt: type = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: type = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %return.param: ref type = out_param runtime_param0 +// CHECK:STDOUT: %return: ref type = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: .M = +// CHECK:STDOUT: witness = file.%impl_witness.loc11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.be1: %C as %.loc17_17 { +// CHECK:STDOUT: %G.decl: %G.type.875 = fn_decl @G.3 [concrete = constants.%G.702] { +// CHECK:STDOUT: %return.patt: type = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: type = out_param_pattern %return.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %return.param: ref type = out_param runtime_param0 +// CHECK:STDOUT: %return: ref type = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: .M = +// CHECK:STDOUT: witness = file.%impl_witness.loc17 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(%T.loc4_9.1: type) { +// CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc4_9.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_9.2 (constants.%T.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.f2e +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @G.1(@M.%Self: %M.type) { +// CHECK:STDOUT: fn() -> type; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @G.2() -> type { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.b80.%C [concrete = constants.%C.7a7] +// CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] +// CHECK:STDOUT: %M.facet: %M.type = facet_value constants.%C.7a7, constants.%impl_witness.046 [concrete = constants.%M.facet.f90] +// CHECK:STDOUT: %.loc13_18: %M.type = converted %Self.ref, %M.facet [concrete = constants.%M.facet.f90] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %as_type: type = facet_access_type %.loc13_18 [concrete = constants.%C.7a7] +// CHECK:STDOUT: %.loc13_23: type = converted %.loc13_18, %as_type [concrete = constants.%C.7a7] +// CHECK:STDOUT: %as_wit: = facet_access_witness %.loc13_18 [concrete = constants.%impl_witness.046] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.86f = impl_witness_access %as_wit, element0 [concrete = constants.%struct.0f3] +// CHECK:STDOUT: %.loc13_25: type = struct_access %impl.elem0, element0 [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: return %.loc13_25 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @G.3() -> type { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.be1.%C [concrete = constants.%C.3a0] +// CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] +// CHECK:STDOUT: %M.facet: %M.type = facet_value constants.%C.3a0, constants.%impl_witness.e37 [concrete = constants.%M.facet.2a4] +// CHECK:STDOUT: %.loc19_18: %M.type = converted %Self.ref, %M.facet [concrete = constants.%M.facet.2a4] +// CHECK:STDOUT: %Z.ref: %M.assoc_type = name_ref Z, @Z.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %as_type: type = facet_access_type %.loc19_18 [concrete = constants.%C.3a0] +// CHECK:STDOUT: %.loc19_23: type = converted %.loc19_18, %as_type [concrete = constants.%C.3a0] +// CHECK:STDOUT: %as_wit: = facet_access_witness %.loc19_18 [concrete = constants.%impl_witness.e37] +// CHECK:STDOUT: %impl.elem0: %struct_type.b.86f = impl_witness_access %as_wit, element0 [concrete = constants.%struct.c94] +// CHECK:STDOUT: %.loc19_25: type = struct_access %impl.elem0, element0 [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: return %.loc19_25 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @G.1(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%empty_struct_type) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%M.facet.ba5) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @G.1(constants.%M.facet.f90) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%M.facet.f90) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%empty_tuple.type) { +// CHECK:STDOUT: %T.loc4_9.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %T.patt.loc4_9.2 => constants.%empty_tuple.type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @G.1(constants.%M.facet.2a4) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%M.facet.2a4) {} +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_associated_int_in_array.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon index 69d454e4a09d1..60a6c7ec1677c 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_cycle.carbon @@ -181,6 +181,21 @@ fn F() { // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: Compare({} as C, {} as D); + + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE+13]]:3: error: cycle found in search for impl of `ComparableWith(D)` for type `C` [ImplLookupCycle] + // CHECK:STDERR: Compare({} as D, {} as C); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-50]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] + // CHECK:STDERR: impl forall [U:! type, T:! ComparableWith(U)] + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-53]]:1: note: determining if this impl clause matches [ImplLookupCycleNote] + // CHECK:STDERR: impl forall [U:! type, T:! ComparableWith(U)] + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_cycle_one_generic_param.carbon:[[@LINE-49]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn Compare[T:! type, U:! ComparableWith(T)](t: T, u: U) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + Compare({} as D, {} as C); } // --- impl_recurse_with_simpler_type_no_cycle.carbon diff --git a/toolchain/sem_ir/constant.h b/toolchain/sem_ir/constant.h index 67a47028cfd87..bbe84857d8915 100644 --- a/toolchain/sem_ir/constant.h +++ b/toolchain/sem_ir/constant.h @@ -118,13 +118,6 @@ class ConstantValueStore { return GetInstId(Get(inst_id)); } - // Returns whether two constant IDs represent the same constant value. This - // includes the case where they might be in different generics and thus might - // have different ConstantIds, but are still symbolically equal. - auto AreEqualAcrossDeclarations(ConstantId a, ConstantId b) const -> bool { - return GetInstId(a) == GetInstId(b); - } - auto AddSymbolicConstant(SymbolicConstant constant) -> ConstantId { symbolic_constants_.push_back(constant); return ConstantId::ForSymbolicConstantIndex(symbolic_constants_.size() - 1); From 2311595b2758ec4f8433e9b7eb3e91d15e729cbc Mon Sep 17 00:00:00 2001 From: danakj Date: Fri, 28 Feb 2025 18:50:08 -0500 Subject: [PATCH 02/21] rename-test-file --- .../check/testdata/facet/no_prelude/combine.carbon | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon index c369ec17d5bbe..2c77c6159a7ba 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine.carbon +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -225,7 +225,7 @@ fn F() { (({} as C) as (C as (A(P2) & B))).(B.G)(); } -// --- todo_generic_interface_parameter.carbon +// --- fail_todo_generic_interface_parameter.carbon library "[[@TEST_NAME]]"; import Core; @@ -249,12 +249,12 @@ fn G[T:! A & B](t: T) { // TODO: Lookup of `AA` and `BB` should be possible here, using the witnesses // found in type deduction. - // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] // CHECK:STDERR: t.AA(); // CHECK:STDERR: ^~~~ // CHECK:STDERR: t.AA(); - // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] // CHECK:STDERR: t.BB(); // CHECK:STDERR: ^~~~ // CHECK:STDERR: @@ -263,12 +263,12 @@ fn G[T:! A & B](t: T) { // TODO: Qualified lookup of `AA` and `BB` should also be possible here, using // the witnesses found in type deduction. - // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `T` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `T` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: t.(A.AA)(); // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: t.(A.AA)(); - // CHECK:STDERR: todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: t.(B.BB)(); // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: From e0224bf9712b030fb2accdf7ad5352597e752d30 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:44:24 -0500 Subject: [PATCH 03/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index c5f88b5d0f492..d870096d585d7 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -157,7 +157,7 @@ static auto FindAndDiagnoseImplLookupCycle( return false; } -// Gets the set of `SemIR::InterfaceId`s that are available given a facet type +// Gets the set of `SpecificInterface`s that are required by a facet type // (as a constant value). static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, SemIR::ConstantId interface_const_id) From 6030c64512d2044a1c3e93539ae58805af8ce73a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:49:21 -0500 Subject: [PATCH 04/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index d870096d585d7..ac11eb8062b4b 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -214,12 +214,6 @@ static auto GetWitnessIdForImpl( return SemIR::InstId::None; } - // impl C as A where .Self impls I {} - - // ({} as C) as (C as (A & B)) - // ^ FacetValue witnesses for A and B - // ^ CompleteFacetType has 2 required_interfaces - // When the impl's interface_id matches, but the interface is generic, the // impl may or may not match based on restrictions in the generic parameters // of the impl. From fa27e2345707ef118ff4e573a4cc9ecf51a7ea01 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:50:38 -0500 Subject: [PATCH 05/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index ac11eb8062b4b..f5a9897ed8328 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -219,7 +219,7 @@ static auto GetWitnessIdForImpl( // of the impl. // // As a shortcut, if the impl's constraint is not symbolic (does not depend on - // any generic parameters), then we can determine if we match if the specific + // any generic parameters), then we can determine that we match if the specific // ids match exactly. auto impl_interface_const_id = context.constant_values().Get(impl.constraint_id); From 0e2ae7079ab62b554cb9dd1f22bc243d8f96cd74 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:53:30 -0500 Subject: [PATCH 06/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index f5a9897ed8328..11eb90d04b6ab 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -354,7 +354,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, .type_const_id = type_const_id, .interface_const_id = interface_const_id, }); - // We need to find a witness for each interface in `interface_ids`. We return + // We need to find a witness for each interface in `interfaces`. We return // them in the same order as they are found in the `CompleteFacetType`, which // is the same order as in `interface_ids` here. for (const auto& [interface, interface_has_other_requirements] : interfaces) { From 56a7d9eaee565b1581920b725c28e1bbeb368ce1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:53:48 -0500 Subject: [PATCH 07/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 11eb90d04b6ab..575091a8b5b12 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -356,7 +356,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, }); // We need to find a witness for each interface in `interfaces`. We return // them in the same order as they are found in the `CompleteFacetType`, which - // is the same order as in `interface_ids` here. + // is the same order as in `interfaces` here. for (const auto& [interface, interface_has_other_requirements] : interfaces) { bool found_witness = false; for (const auto& impl : context.impls().array_ref()) { From 6f6230f44b3bdfb86113e9538fba2dde8fc083b3 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:54:07 -0500 Subject: [PATCH 08/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 575091a8b5b12..cad3214d43dbd 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -343,7 +343,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, GetInterfacesFromConstantId(context, loc_id, interface_const_id); if (interfaces.empty()) { // TODO: Remove this when the context.TODO() is removed in - // GetInterfaceIdsFromConstantId. + // GetInterfacesFromConstantId. return SemIR::InstId::None; } From beeaf0e62dd82b13155dcb15ecee3798d961dc8c Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 11:52:45 -0500 Subject: [PATCH 09/21] check witness value is not none --- toolchain/check/impl_lookup.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index cad3214d43dbd..48bd4f094c92e 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -235,10 +235,7 @@ static auto GetWitnessIdForImpl( if (impl.witness_id == SemIR::ErrorInst::SingletonInstId) { return SemIR::InstId::None; } - if (!impl.witness_id.has_value()) { - // TODO: Diagnose if the impl isn't defined yet? - return SemIR::InstId::None; - } + CARBON_CHECK(impl.witness_id.has_value()); // The impl may have generic arguments, in which case we need to deduce them // to find what they are given the specific interface query. We use that From 281a764fd040ad972c5d7040899b7d47163134a6 Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 11:54:44 -0500 Subject: [PATCH 10/21] format --- toolchain/check/impl_lookup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 48bd4f094c92e..01313f6c6c7d5 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -219,8 +219,8 @@ static auto GetWitnessIdForImpl( // of the impl. // // As a shortcut, if the impl's constraint is not symbolic (does not depend on - // any generic parameters), then we can determine that we match if the specific - // ids match exactly. + // any generic parameters), then we can determine that we match if the + // specific ids match exactly. auto impl_interface_const_id = context.constant_values().Get(impl.constraint_id); if (!impl_interface_const_id.is_symbolic()) { From c91d5126e95cbe4de6854763e478eaa64a2a6427 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:55:56 -0500 Subject: [PATCH 11/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 01313f6c6c7d5..378b6de7af245 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -363,7 +363,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, interface_has_other_requirements, impl); if (result_witness_id.has_value()) { result_witness_ids.push_back(result_witness_id); - // We found a matching impl; don't keep looking for this `interface_id`, + // We found a matching impl; don't keep looking for this `interface`, // move onto the next. found_witness = true; break; From fe971dac7d59568f9b4d2504fb1441d73abe39bf Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 3 Mar 2025 11:56:42 -0500 Subject: [PATCH 12/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 378b6de7af245..4f5b9a6045c35 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -238,7 +238,7 @@ static auto GetWitnessIdForImpl( CARBON_CHECK(impl.witness_id.has_value()); // The impl may have generic arguments, in which case we need to deduce them - // to find what they are given the specific interface query. We use that + // 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. auto specific_id = SemIR::SpecificId::None; if (impl.generic_id.has_value()) { From ef4e08151b4671d61855d9fed9c50bba62494c1d Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 11:57:00 -0500 Subject: [PATCH 13/21] format --- toolchain/check/impl_lookup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 4f5b9a6045c35..a66733976b2c7 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -238,8 +238,8 @@ static auto GetWitnessIdForImpl( CARBON_CHECK(impl.witness_id.has_value()); // 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. + // 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. auto specific_id = SemIR::SpecificId::None; if (impl.generic_id.has_value()) { specific_id = DeduceImplArguments(context, loc_id, impl, type_const_id, From 5df7e940fe277e7f3b98583a8abbcb7ea9e8bc4e Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 12:28:01 -0500 Subject: [PATCH 14/21] avoid crash on wrong facet witness for now, add tests --- toolchain/check/eval_inst.cpp | 9 + .../testdata/facet/no_prelude/combine.carbon | 200 ++--- .../facet/no_prelude/combine_witness.carbon | 847 ++++++++++++++++++ 3 files changed, 916 insertions(+), 140 deletions(-) create mode 100644 toolchain/check/testdata/facet/no_prelude/combine_witness.carbon diff --git a/toolchain/check/eval_inst.cpp b/toolchain/check/eval_inst.cpp index dfac6ce843811..16d81374c0413 100644 --- a/toolchain/check/eval_inst.cpp +++ b/toolchain/check/eval_inst.cpp @@ -8,6 +8,7 @@ #include "toolchain/check/import_ref.h" #include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { @@ -199,6 +200,14 @@ auto EvalConstantInst(Context& context, SemIRLoc loc, context.insts().TryGetAs(inst.witness_id)) { auto elements = context.inst_blocks().Get(witness->elements_id); auto index = static_cast(inst.index.index); + // TODO: Remove this block when LookupImplWitness returns all the witnesses + // for a facet type instead of just one. We just don't want to introduce + // crashes in the meantime. + if (index >= elements.size()) { + context.TODO(loc, + "incorrect witness for multiple interfaces in a facet type"); + return ConstantEvalResult::Error; + } CARBON_CHECK(index < elements.size(), "Access out of bounds."); auto element = elements[index]; if (!element.has_value()) { diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon index 2c77c6159a7ba..5cafc2e23b6d7 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine.carbon +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -37,6 +37,26 @@ import Core; interface A {} class C {} +// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] +// CHECK:STDERR: fn AC[T:! A & C](t: T) {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +fn AC[T:! A & C](t: T) {} +// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] +// CHECK:STDERR: fn CA[T:! C & A](t: T) {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +fn CA[T:! C & A](t: T) {} +// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+8]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] +// CHECK:STDERR: fn CC[T:! C & C](t: T) {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] +// CHECK:STDERR: fn CC[T:! C & C](t: T) {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +fn CC[T:! C & C](t: T) {} + fn F() { // CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator] // CHECK:STDERR: ({} as C) as (C as (A & C)); @@ -57,6 +77,10 @@ fn F() { // CHECK:STDERR: ^~~~~ // CHECK:STDERR: ({} as C) as (C as (C & C)); + + AC({} as C); + CA({} as C); + CC({} as C); } // --- same.carbon @@ -64,19 +88,17 @@ library "[[@TEST_NAME]]"; import Core; -interface A { - fn G(); -} +interface A {} class C {} -impl C as A { - fn G() {} -} +impl C as A {} + +fn AA[T:! A & A](t: T) {} fn F() { - ({} as C).((A & A).G)(); - (({} as C) as (C as (A & A))).((A & A).G)(); - (({} as C) as (C as (A & A))).(A.G)(); + ({} as C) as (C as (A & A)); + + AA({} as C); } // --- fail_name_collision.carbon @@ -133,66 +155,25 @@ fn F() { (({} as C) as (C as (A & B))).((B).G)(); } -// --- fail_todo_generic_param_is_combined.carbon - -library "[[@TEST_NAME]]"; - -import Core; - -interface A { - fn G(); -} -interface B { - fn H(); -} - -fn G[T:! A & B](t: T) { - // CHECK:STDERR: fail_todo_generic_param_is_combined.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: t.G(); - // CHECK:STDERR: ^~~ - // CHECK:STDERR: - t.G(); - // CHECK:STDERR: fail_todo_generic_param_is_combined.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: t.H(); - // CHECK:STDERR: ^~~ - // CHECK:STDERR: - t.H(); -} - -class C {} -impl C as A { - fn G() {} -} -impl C as B { - fn H() {} -} - -fn F() { - G({} as C); -} - -// --- todo_generic_interface.carbon +// --- generic_interface.carbon library "[[@TEST_NAME]]"; import Core; interface A(T:! type) {} -interface B { - fn G(); -} +interface B {} class P1 {} class P2 {} class C {} impl C as A(P1) {} -impl C as B { - fn G() {} -} +impl C as B {} + +fn G[T:! A(P1) & B](t: T) {} fn F() { - // TODO: Qualified lookup of `G` should not be needed here. - (({} as C) as (C as (A(P1) & B))).(B.G)(); + G({} as C); } // --- fail_wrong_generic_interface.carbon @@ -201,112 +182,51 @@ library "[[@TEST_NAME]]"; import Core; interface A(T:! type) {} -interface B { - fn G(); -} +interface B {} class P1 {} class P2 {} class C {} impl C as A(P1) {} -impl C as B { - fn G() {} -} - -fn F() { - // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+7]]:18: error: cannot convert from `type` to `A(P2) & B` with `as` [ExplicitAsConversionFailure] - // CHECK:STDERR: (({} as C) as (C as (A(P2) & B))).(B.G)(); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+4]]:18: note: type `type` does not implement interface `Core.As(A(P2) & B)` [MissingImplInMemberAccessNote] - // CHECK:STDERR: (({} as C) as (C as (A(P2) & B))).(B.G)(); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~ - // CHECK:STDERR: - (({} as C) as (C as (A(P2) & B))).(B.G)(); -} +impl C as B {} -// --- fail_todo_generic_interface_parameter.carbon -library "[[@TEST_NAME]]"; - -import Core; - -interface A { - fn AA(); -} -interface B { - fn BB(); -} - -class C {} -impl C as A { - fn AA() {} -} -impl C as B { - fn BB() {} -} - -fn G[T:! A & B](t: T) { - // TODO: Lookup of `AA` and `BB` should be possible here, using the witnesses - // found in type deduction. - - // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: t.AA(); - // CHECK:STDERR: ^~~~ - // CHECK:STDERR: - t.AA(); - // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: t.BB(); - // CHECK:STDERR: ^~~~ - // CHECK:STDERR: - t.BB(); - - // TODO: Qualified lookup of `AA` and `BB` should also be possible here, using - // the witnesses found in type deduction. - - // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `T` that does not implement that interface [MissingImplInMemberAccess] - // CHECK:STDERR: t.(A.AA)(); - // CHECK:STDERR: ^~~~~~~~ - // CHECK:STDERR: - t.(A.AA)(); - // CHECK:STDERR: fail_todo_generic_interface_parameter.carbon:[[@LINE+4]]:3: error: cannot access member of interface `B` in type `T` that does not implement that interface [MissingImplInMemberAccess] - // CHECK:STDERR: t.(B.BB)(); - // CHECK:STDERR: ^~~~~~~~ - // CHECK:STDERR: - t.(B.BB)(); -} +fn G[T:! A(P2) & B](t: T) {} fn F() { + // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+10]]:3: error: cannot implicitly convert from `type` to `A(P2) & B` [ImplicitAsConversionFailure] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(A(P2) & B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_wrong_generic_interface.carbon:[[@LINE-9]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn G[T:! A(P2) & B](t: T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: G({} as C); } - -// --- todo_generic_forall_impl.carbon +// --- generic_forall_impl.carbon library "[[@TEST_NAME]]"; import Core; -interface Iface { fn Q(); } -interface GenericIface(T:! type) { fn R(); } +interface Iface {} +interface GenericIface(T:! type) {} class GenericClass(T:! type) {} +class ImplIface {} +impl ImplIface as Iface {} + class C {} -impl C as Iface { fn Q() {} } +impl C as Iface {} -impl forall [IfaceType:! Iface] C as GenericIface(GenericClass(IfaceType)) { - fn R() {} -} +impl forall [IfaceType:! Iface] C as GenericIface(GenericClass(IfaceType)) {} -class ImplIface {} -impl ImplIface as Iface { fn Q() {} } +fn G[T:! Iface & GenericIface(GenericClass(ImplIface))](t: T) {} fn F() { - ({} as C) as (C as Iface); - ({} as C) as (C as GenericIface(GenericClass(ImplIface))); - - ({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface)))); - - // TODO: Qualified lookup of `Q` and `R` should not be needed here. - (({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface))))).(Iface.Q)(); - (({} as C) as (C as (Iface & GenericIface(GenericClass(ImplIface))))).(GenericIface(GenericClass(ImplIface)).R)(); + G({} as C); } diff --git a/toolchain/check/testdata/facet/no_prelude/combine_witness.carbon b/toolchain/check/testdata/facet/no_prelude/combine_witness.carbon new file mode 100644 index 0000000000000..2a1524601f3ca --- /dev/null +++ b/toolchain/check/testdata/facet/no_prelude/combine_witness.carbon @@ -0,0 +1,847 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/no_prelude/combine_witness.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/no_prelude/combine_witness.carbon + +// --- core.carbon +package Core; + +interface As(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +interface ImplicitAs(Dest:! type) { + fn Convert[self: Self]() -> Dest; +} + +interface BitAnd { + fn Op[self: Self](other: Self) -> Self; +} + +impl forall [T:! type] T as BitAnd { + fn Op[self: Self](other: Self) -> Self = "type.and"; +} + +// --- call_combined_impl_witness.carbon + +library "[[@TEST_NAME]]"; + +import Core; + +interface Empty { +} +interface A { + fn AA(); +} +interface B { + fn BB(); +} + +class C {} +impl C as Empty {} +impl C as A { + fn AA() {} +} +impl C as B { + fn BB() {} +} + +fn G[T:! A & Empty & B](t: T) { + t.AA(); + t.BB(); + + T.AA(); + T.BB(); + + // TODO: Qualified lookup of `AA` and `BB` should also be possible here, using + // the witnesses found in type deduction. + + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: T.(A.AA)(); + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + T.(A.AA)(); + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+7]]:3: error: cannot access member of interface `B` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: T.(B.BB)(); + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE-18]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] + // CHECK:STDERR: t.AA(); + // CHECK:STDERR: ^~~~ + T.(B.BB)(); +} + +fn F() { + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+11]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^ + // CHECK:STDERR: + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE-28]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] + // CHECK:STDERR: t.BB(); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+4]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] + // CHECK:STDERR: G({} as C); + // CHECK:STDERR: ^ + // CHECK:STDERR: + G({} as C); +} + +// CHECK:STDOUT: --- core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic] +// CHECK:STDOUT: %Dest.patt: type = symbolic_binding_pattern Dest, 0 [symbolic] +// CHECK:STDOUT: %As.type.b51: type = generic_interface_type @As [concrete] +// CHECK:STDOUT: %As.generic: %As.type.b51 = struct_value () [concrete] +// CHECK:STDOUT: %As.type.8ba: type = facet_type <@As, @As(%Dest)> [symbolic] +// CHECK:STDOUT: %Self.b4e: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Self.as_type.7f0: type = facet_access_type %Self.b4e [symbolic] +// CHECK:STDOUT: %Convert.type.ad1: type = fn_type @Convert.1, @As(%Dest) [symbolic] +// CHECK:STDOUT: %Convert.0ed: %Convert.type.ad1 = struct_value () [symbolic] +// CHECK:STDOUT: %As.assoc_type: type = assoc_entity_type %As.type.8ba [symbolic] +// CHECK:STDOUT: %assoc0.ac5: %As.assoc_type = assoc_entity element0, @As.%Convert.decl [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.96f: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.96f = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.07f: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic] +// CHECK:STDOUT: %Self.0f3: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Self.as_type.419: type = facet_access_type %Self.0f3 [symbolic] +// CHECK:STDOUT: %Convert.type.4cf: type = fn_type @Convert.2, @ImplicitAs(%Dest) [symbolic] +// CHECK:STDOUT: %Convert.147: %Convert.type.4cf = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type %ImplicitAs.type.07f [symbolic] +// CHECK:STDOUT: %assoc0.a50: %ImplicitAs.assoc_type = assoc_entity element0, @ImplicitAs.%Convert.decl [symbolic] +// CHECK:STDOUT: %BitAnd.type: type = facet_type <@BitAnd> [concrete] +// CHECK:STDOUT: %Self.e44: %BitAnd.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type.560: type = facet_access_type %Self.e44 [symbolic] +// CHECK:STDOUT: %Op.type.613: type = fn_type @Op.1 [concrete] +// CHECK:STDOUT: %Op.d98: %Op.type.613 = struct_value () [concrete] +// CHECK:STDOUT: %BitAnd.assoc_type: type = assoc_entity_type %BitAnd.type [concrete] +// CHECK:STDOUT: %assoc0.121: %BitAnd.assoc_type = assoc_entity element0, @BitAnd.%Op.decl [concrete] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%Op.decl), @impl(%T) [symbolic] +// CHECK:STDOUT: %Op.type.28d: type = fn_type @Op.2, @impl(%T) [symbolic] +// CHECK:STDOUT: %Op.902: %Op.type.28d = struct_value () [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %BitAnd.facet: %BitAnd.type = facet_value %T, %impl_witness [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .As = %As.decl +// CHECK:STDOUT: .ImplicitAs = %ImplicitAs.decl +// CHECK:STDOUT: .BitAnd = %BitAnd.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %As.decl: %As.type.b51 = interface_decl @As [concrete = constants.%As.generic] { +// CHECK:STDOUT: %Dest.patt.loc3_14.1: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc3_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: %Dest.param_patt: type = value_param_pattern %Dest.patt.loc3_14.1, runtime_param [symbolic = %Dest.patt.loc3_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.param: type = value_param runtime_param +// CHECK:STDOUT: %Dest.loc3_14.1: type = bind_symbolic_name Dest, 0, %Dest.param [symbolic = %Dest.loc3_14.2 (constants.%Dest)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %ImplicitAs.decl: %ImplicitAs.type.96f = interface_decl @ImplicitAs [concrete = constants.%ImplicitAs.generic] { +// CHECK:STDOUT: %Dest.patt.loc7_22.1: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc7_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: %Dest.param_patt: type = value_param_pattern %Dest.patt.loc7_22.1, runtime_param [symbolic = %Dest.patt.loc7_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.param: type = value_param runtime_param +// CHECK:STDOUT: %Dest.loc7_22.1: type = bind_symbolic_name Dest, 0, %Dest.param [symbolic = %Dest.loc7_22.2 (constants.%Dest)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %BitAnd.decl: type = interface_decl @BitAnd [concrete = constants.%BitAnd.type] {} {} +// CHECK:STDOUT: impl_decl @impl [concrete] { +// CHECK:STDOUT: %T.patt.loc15_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc15_14.1, runtime_param [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc15_14.1 [symbolic = %T.loc15_14.2 (constants.%T)] +// CHECK:STDOUT: %BitAnd.ref: type = name_ref BitAnd, file.%BitAnd.decl [concrete = constants.%BitAnd.type] +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc15_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc15_14.2 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%Op.decl), @impl(constants.%T) [symbolic = @impl.%impl_witness (constants.%impl_witness)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @As(%Dest.loc3_14.1: type) { +// CHECK:STDOUT: %Dest.loc3_14.2: type = bind_symbolic_name Dest, 0 [symbolic = %Dest.loc3_14.2 (constants.%Dest)] +// CHECK:STDOUT: %Dest.patt.loc3_14.2: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc3_14.2 (constants.%Dest.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %As.type: type = facet_type <@As, @As(%Dest.loc3_14.2)> [symbolic = %As.type (constants.%As.type.8ba)] +// CHECK:STDOUT: %Self.2: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert.1, @As(%Dest.loc3_14.2) [symbolic = %Convert.type (constants.%Convert.type.ad1)] +// CHECK:STDOUT: %Convert: @As.%Convert.type (%Convert.type.ad1) = struct_value () [symbolic = %Convert (constants.%Convert.0ed)] +// CHECK:STDOUT: %As.assoc_type: type = assoc_entity_type @As.%As.type (%As.type.8ba) [symbolic = %As.assoc_type (constants.%As.assoc_type)] +// CHECK:STDOUT: %assoc0.loc4_35.2: @As.%As.assoc_type (%As.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc4_35.2 (constants.%assoc0.ac5)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @As.%As.type (%As.type.8ba) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.b4e)] +// CHECK:STDOUT: %Convert.decl: @As.%Convert.type (%Convert.type.ad1) = fn_decl @Convert.1 [symbolic = @As.%Convert (constants.%Convert.0ed)] { +// CHECK:STDOUT: %self.patt: @Convert.1.%Self.as_type.loc4_20.1 (%Self.as_type.7f0) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Convert.1.%Self.as_type.loc4_20.1 (%Self.as_type.7f0) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: @Convert.1.%Dest (%Dest) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Convert.1.%Dest (%Dest) = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.ref: type = name_ref Dest, @As.%Dest.loc3_14.1 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %self.param: @Convert.1.%Self.as_type.loc4_20.1 (%Self.as_type.7f0) = value_param runtime_param0 +// CHECK:STDOUT: %.loc4_20.1: type = splice_block %.loc4_20.3 [symbolic = %Self.as_type.loc4_20.1 (constants.%Self.as_type.7f0)] { +// CHECK:STDOUT: %.loc4_20.2: @Convert.1.%As.type (%As.type.8ba) = specific_constant @As.%Self.1, @As(constants.%Dest) [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.ref: @Convert.1.%As.type (%As.type.8ba) = name_ref Self, %.loc4_20.2 [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.as_type.loc4_20.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc4_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: %.loc4_20.3: type = converted %Self.ref, %Self.as_type.loc4_20.2 [symbolic = %Self.as_type.loc4_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Convert.1.%Self.as_type.loc4_20.1 (%Self.as_type.7f0) = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref @Convert.1.%Dest (%Dest) = out_param runtime_param1 +// CHECK:STDOUT: %return: ref @Convert.1.%Dest (%Dest) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc4_35.1: @As.%As.assoc_type (%As.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc4_35.2 (constants.%assoc0.ac5)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .Dest = +// CHECK:STDOUT: .Convert = %assoc0.loc4_35.1 +// CHECK:STDOUT: witness = (%Convert.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @ImplicitAs(%Dest.loc7_22.1: type) { +// CHECK:STDOUT: %Dest.loc7_22.2: type = bind_symbolic_name Dest, 0 [symbolic = %Dest.loc7_22.2 (constants.%Dest)] +// CHECK:STDOUT: %Dest.patt.loc7_22.2: type = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc7_22.2 (constants.%Dest.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest.loc7_22.2)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.07f)] +// CHECK:STDOUT: %Self.2: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert.2, @ImplicitAs(%Dest.loc7_22.2) [symbolic = %Convert.type (constants.%Convert.type.4cf)] +// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.4cf) = struct_value () [symbolic = %Convert (constants.%Convert.147)] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type)] +// CHECK:STDOUT: %assoc0.loc8_35.2: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc8_35.2 (constants.%assoc0.a50)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self.0f3)] +// CHECK:STDOUT: %Convert.decl: @ImplicitAs.%Convert.type (%Convert.type.4cf) = fn_decl @Convert.2 [symbolic = @ImplicitAs.%Convert (constants.%Convert.147)] { +// CHECK:STDOUT: %self.patt: @Convert.2.%Self.as_type.loc8_20.1 (%Self.as_type.419) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Convert.2.%Self.as_type.loc8_20.1 (%Self.as_type.419) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %return.patt: @Convert.2.%Dest (%Dest) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Convert.2.%Dest (%Dest) = out_param_pattern %return.patt, runtime_param1 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Dest.ref: type = name_ref Dest, @ImplicitAs.%Dest.loc7_22.1 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %self.param: @Convert.2.%Self.as_type.loc8_20.1 (%Self.as_type.419) = value_param runtime_param0 +// CHECK:STDOUT: %.loc8_20.1: type = splice_block %.loc8_20.3 [symbolic = %Self.as_type.loc8_20.1 (constants.%Self.as_type.419)] { +// CHECK:STDOUT: %.loc8_20.2: @Convert.2.%ImplicitAs.type (%ImplicitAs.type.07f) = specific_constant @ImplicitAs.%Self.1, @ImplicitAs(constants.%Dest) [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.ref: @Convert.2.%ImplicitAs.type (%ImplicitAs.type.07f) = name_ref Self, %.loc8_20.2 [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.as_type.loc8_20.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc8_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: %.loc8_20.3: type = converted %Self.ref, %Self.as_type.loc8_20.2 [symbolic = %Self.as_type.loc8_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Convert.2.%Self.as_type.loc8_20.1 (%Self.as_type.419) = bind_name self, %self.param +// CHECK:STDOUT: %return.param: ref @Convert.2.%Dest (%Dest) = out_param runtime_param1 +// CHECK:STDOUT: %return: ref @Convert.2.%Dest (%Dest) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc8_35.1: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type) = assoc_entity element0, %Convert.decl [symbolic = %assoc0.loc8_35.2 (constants.%assoc0.a50)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .Dest = +// CHECK:STDOUT: .Convert = %assoc0.loc8_35.1 +// CHECK:STDOUT: witness = (%Convert.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @BitAnd { +// CHECK:STDOUT: %Self: %BitAnd.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.e44] +// CHECK:STDOUT: %Op.decl: %Op.type.613 = fn_decl @Op.1 [concrete = constants.%Op.d98] { +// CHECK:STDOUT: %self.patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %other.patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = binding_pattern other +// CHECK:STDOUT: %other.param_patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = value_param_pattern %other.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = out_param_pattern %return.patt, runtime_param2 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.ref.loc12_37: %BitAnd.type = name_ref Self, @BitAnd.%Self [symbolic = %Self (constants.%Self.e44)] +// CHECK:STDOUT: %Self.as_type.loc12_37: type = facet_access_type %Self.ref.loc12_37 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: %.loc12_37: type = converted %Self.ref.loc12_37, %Self.as_type.loc12_37 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: %self.param: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = value_param runtime_param0 +// CHECK:STDOUT: %.loc12_15.1: type = splice_block %.loc12_15.2 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] { +// CHECK:STDOUT: %Self.ref.loc12_15: %BitAnd.type = name_ref Self, @BitAnd.%Self [symbolic = %Self (constants.%Self.e44)] +// CHECK:STDOUT: %Self.as_type.loc12_15.2: type = facet_access_type %Self.ref.loc12_15 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: %.loc12_15.2: type = converted %Self.ref.loc12_15, %Self.as_type.loc12_15.2 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = bind_name self, %self.param +// CHECK:STDOUT: %other.param: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = value_param runtime_param1 +// CHECK:STDOUT: %.loc12_28.1: type = splice_block %.loc12_28.2 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] { +// CHECK:STDOUT: %Self.ref.loc12_28: %BitAnd.type = name_ref Self, @BitAnd.%Self [symbolic = %Self (constants.%Self.e44)] +// CHECK:STDOUT: %Self.as_type.loc12_28: type = facet_access_type %Self.ref.loc12_28 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: %.loc12_28.2: type = converted %Self.ref.loc12_28, %Self.as_type.loc12_28 [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %other: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = bind_name other, %other.param +// CHECK:STDOUT: %return.param: ref @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = out_param runtime_param2 +// CHECK:STDOUT: %return: ref @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %BitAnd.assoc_type = assoc_entity element0, %Op.decl [concrete = constants.%assoc0.121] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Op = %assoc0 +// CHECK:STDOUT: witness = (%Op.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @impl(%T.loc15_14.1: type) { +// CHECK:STDOUT: %T.loc15_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_14.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc15_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc15_14.2 (constants.%T.patt)] +// CHECK:STDOUT: %impl_witness: = impl_witness (%Op.decl), @impl(%T.loc15_14.2) [symbolic = %impl_witness (constants.%impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Op.type: type = fn_type @Op.2, @impl(%T.loc15_14.2) [symbolic = %Op.type (constants.%Op.type.28d)] +// CHECK:STDOUT: %Op: @impl.%Op.type (%Op.type.28d) = struct_value () [symbolic = %Op (constants.%Op.902)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.%T.loc15_14.2 (%T) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: %T.ref as %BitAnd.ref { +// CHECK:STDOUT: %Op.decl: @impl.%Op.type (%Op.type.28d) = fn_decl @Op.2 [symbolic = @impl.%Op (constants.%Op.902)] { +// CHECK:STDOUT: %self.patt: @Op.2.%T (%T) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @Op.2.%T (%T) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %other.patt: @Op.2.%T (%T) = binding_pattern other +// CHECK:STDOUT: %other.param_patt: @Op.2.%T (%T) = value_param_pattern %other.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: @Op.2.%T (%T) = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: @Op.2.%T (%T) = out_param_pattern %return.patt, runtime_param2 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.ref.loc16_37: type = name_ref Self, @impl.%T.ref [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %self.param: @Op.2.%T (%T) = value_param runtime_param0 +// CHECK:STDOUT: %Self.ref.loc16_15: type = name_ref Self, @impl.%T.ref [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %self: @Op.2.%T (%T) = bind_name self, %self.param +// CHECK:STDOUT: %other.param: @Op.2.%T (%T) = value_param runtime_param1 +// CHECK:STDOUT: %Self.ref.loc16_28: type = name_ref Self, @impl.%T.ref [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %other: @Op.2.%T (%T) = bind_name other, %other.param +// CHECK:STDOUT: %return.param: ref @Op.2.%T (%T) = out_param runtime_param2 +// CHECK:STDOUT: %return: ref @Op.2.%T (%T) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Op.decl +// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert.1(@As.%Dest.loc3_14.1: type, @As.%Self.1: @As.%As.type (%As.type.8ba)) { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %As.type: type = facet_type <@As, @As(%Dest)> [symbolic = %As.type (constants.%As.type.8ba)] +// CHECK:STDOUT: %Self: %As.type.8ba = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.b4e)] +// CHECK:STDOUT: %Self.as_type.loc4_20.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc4_20.1 (constants.%Self.as_type.7f0)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.1.%Self.as_type.loc4_20.1 (%Self.as_type.7f0)]() -> @Convert.1.%Dest (%Dest); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert.2(@ImplicitAs.%Dest.loc7_22.1: type, @ImplicitAs.%Self.1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.07f)) { +// CHECK:STDOUT: %Dest: type = bind_symbolic_name Dest, 0 [symbolic = %Dest (constants.%Dest)] +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%Dest)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.07f)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.07f = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.0f3)] +// CHECK:STDOUT: %Self.as_type.loc8_20.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc8_20.1 (constants.%Self.as_type.419)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.2.%Self.as_type.loc8_20.1 (%Self.as_type.419)]() -> @Convert.2.%Dest (%Dest); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Op.1(@BitAnd.%Self: %BitAnd.type) { +// CHECK:STDOUT: %Self: %BitAnd.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.e44)] +// CHECK:STDOUT: %Self.as_type.loc12_15.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc12_15.1 (constants.%Self.as_type.560)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560)](%other.param_patt: @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560)) -> @Op.1.%Self.as_type.loc12_15.1 (%Self.as_type.560); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Op.2(@impl.%T.loc15_14.1: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Op.2.%T (%T)](%other.param_patt: @Op.2.%T (%T)) -> @Op.2.%T (%T) = "type.and"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(constants.%Dest) { +// CHECK:STDOUT: %Dest.loc3_14.2 => constants.%Dest +// CHECK:STDOUT: %Dest.patt.loc3_14.2 => constants.%Dest +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert.1(constants.%Dest, constants.%Self.b4e) { +// CHECK:STDOUT: %Dest => constants.%Dest +// CHECK:STDOUT: %As.type => constants.%As.type.8ba +// CHECK:STDOUT: %Self => constants.%Self.b4e +// CHECK:STDOUT: %Self.as_type.loc4_20.1 => constants.%Self.as_type.7f0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(@Convert.1.%Dest) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @As(%Dest.loc3_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%Dest) { +// CHECK:STDOUT: %Dest.loc7_22.2 => constants.%Dest +// CHECK:STDOUT: %Dest.patt.loc7_22.2 => constants.%Dest +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert.2(constants.%Dest, constants.%Self.0f3) { +// CHECK:STDOUT: %Dest => constants.%Dest +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.07f +// CHECK:STDOUT: %Self => constants.%Self.0f3 +// CHECK:STDOUT: %Self.as_type.loc8_20.1 => constants.%Self.as_type.419 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(@Convert.2.%Dest) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(%Dest.loc7_22.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.1(constants.%Self.e44) { +// CHECK:STDOUT: %Self => constants.%Self.e44 +// CHECK:STDOUT: %Self.as_type.loc12_15.1 => constants.%Self.as_type.560 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%T) { +// CHECK:STDOUT: %T.loc15_14.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc15_14.2 => constants.%T +// CHECK:STDOUT: %impl_witness => constants.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(%T.loc15_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.2(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.1(constants.%BitAnd.facet) { +// CHECK:STDOUT: %Self => constants.%BitAnd.facet +// CHECK:STDOUT: %Self.as_type.loc12_15.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- call_combined_impl_witness.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Empty.type: type = facet_type <@Empty> [concrete] +// CHECK:STDOUT: %Self.193: %Empty.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] +// CHECK:STDOUT: %Self.31d: %A.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %AA.type.b97: type = fn_type @AA.1 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %AA.c3a: %AA.type.b97 = struct_value () [concrete] +// CHECK:STDOUT: %A.assoc_type: type = assoc_entity_type %A.type [concrete] +// CHECK:STDOUT: %assoc0.f33: %A.assoc_type = assoc_entity element0, @A.%AA.decl [concrete] +// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete] +// CHECK:STDOUT: %Self.783: %B.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %BB.type.64d: type = fn_type @BB.1 [concrete] +// CHECK:STDOUT: %BB.11b: %BB.type.64d = struct_value () [concrete] +// CHECK:STDOUT: %B.assoc_type: type = assoc_entity_type %B.type [concrete] +// CHECK:STDOUT: %assoc0.019: %B.assoc_type = assoc_entity element0, @B.%BB.decl [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %impl_witness.1bc: = impl_witness () [concrete] +// CHECK:STDOUT: %impl_witness.97a: = impl_witness (@impl.77d.%AA.decl) [concrete] +// CHECK:STDOUT: %AA.type.c29: type = fn_type @AA.2 [concrete] +// CHECK:STDOUT: %AA.95d: %AA.type.c29 = struct_value () [concrete] +// CHECK:STDOUT: %A.facet.afe: %A.type = facet_value %C, %impl_witness.97a [concrete] +// CHECK:STDOUT: %impl_witness.fe4: = impl_witness (@impl.c94.%BB.decl) [concrete] +// CHECK:STDOUT: %BB.type.24d: type = fn_type @BB.2 [concrete] +// CHECK:STDOUT: %BB.fe8: %BB.type.24d = struct_value () [concrete] +// CHECK:STDOUT: %B.facet.3a2: %B.type = facet_value %C, %impl_witness.fe4 [concrete] +// CHECK:STDOUT: %BitAnd.type: type = facet_type <@BitAnd> [concrete] +// CHECK:STDOUT: %Self.25f: %BitAnd.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %BitAnd.assoc_type: type = assoc_entity_type %BitAnd.type [concrete] +// CHECK:STDOUT: %assoc0.a63: %BitAnd.assoc_type = assoc_entity element0, imports.%Core.import_ref.a93 [concrete] +// CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.e01: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %impl_witness.db8: = impl_witness (imports.%Core.import_ref.1e6), @impl.f92(%T.8b3) [symbolic] +// CHECK:STDOUT: %Op.type.f99: type = fn_type @Op.1, @impl.f92(%T.8b3) [symbolic] +// CHECK:STDOUT: %Op.05a: %Op.type.f99 = struct_value () [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T.8b3 [symbolic] +// CHECK:STDOUT: %impl_witness.3ea: = impl_witness (imports.%Core.import_ref.1e6), @impl.f92(type) [concrete] +// CHECK:STDOUT: %impl_witness.b81: = impl_witness (imports.%Core.import_ref.bd4), @impl.f92(%T.8b3) [symbolic] +// CHECK:STDOUT: %Op.type.eb8: type = fn_type @Op.1, @impl.f92(type) [concrete] +// CHECK:STDOUT: %Op.444: %Op.type.eb8 = struct_value () [concrete] +// CHECK:STDOUT: %complete_type.473: = complete_type_witness type [concrete] +// CHECK:STDOUT: %Op.type.27a: type = fn_type @Op.2 [concrete] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.25f [symbolic] +// CHECK:STDOUT: %BitAnd.facet: %BitAnd.type = facet_value type, %impl_witness.3ea [concrete] +// CHECK:STDOUT: %.d4d: type = fn_type_with_self_type %Op.type.27a, %BitAnd.facet [concrete] +// CHECK:STDOUT: %Op.bound.6b1: = bound_method %A.type, %Op.444 [concrete] +// CHECK:STDOUT: %Op.specific_fn.b4b: = specific_function %Op.bound.6b1, @Op.1(type) [concrete] +// CHECK:STDOUT: %facet_type.d5f: type = facet_type <@Empty & @A> [concrete] +// CHECK:STDOUT: %Op.bound.b5b: = bound_method %facet_type.d5f, %Op.444 [concrete] +// CHECK:STDOUT: %Op.specific_fn.165: = specific_function %Op.bound.b5b, @Op.1(type) [concrete] +// CHECK:STDOUT: %facet_type.242: type = facet_type <@Empty & @A & @B> [concrete] +// CHECK:STDOUT: %T.2df: %facet_type.242 = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.fd9: %facet_type.242 = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.2df [symbolic] +// CHECK:STDOUT: %G.type: type = fn_type @G [concrete] +// CHECK:STDOUT: %G: %G.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.383: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %T.as_wit: = facet_access_witness %T.2df [symbolic] +// CHECK:STDOUT: %A.facet.d6d: %A.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.124: type = fn_type_with_self_type %AA.type.b97, %A.facet.d6d [symbolic] +// CHECK:STDOUT: %impl.elem0.2b1: %.124 = impl_witness_access %T.as_wit, element0 [symbolic] +// CHECK:STDOUT: %specific_fn.80f: = specific_function %impl.elem0.2b1, @AA.1(%A.facet.d6d) [symbolic] +// CHECK:STDOUT: %B.facet.1c2: %B.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.e3a: type = fn_type_with_self_type %BB.type.64d, %B.facet.1c2 [symbolic] +// CHECK:STDOUT: %impl.elem0.f5b: %.e3a = impl_witness_access %T.as_wit, element0 [symbolic] +// CHECK:STDOUT: %specific_fn.62f: = specific_function %impl.elem0.f5b, @BB.1(%B.facet.1c2) [symbolic] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %facet_value: %facet_type.242 = facet_value %C, %impl_witness.1bc [concrete] +// CHECK:STDOUT: %G.specific_fn: = specific_function %G, @G(%facet_value) [concrete] +// CHECK:STDOUT: %A.facet.beb: %A.type = facet_value %C, %impl_witness.1bc [concrete] +// CHECK:STDOUT: %.778: type = fn_type_with_self_type %AA.type.b97, %A.facet.beb [concrete] +// CHECK:STDOUT: %B.facet.5e0: %B.type = facet_value %C, %impl_witness.1bc [concrete] +// CHECK:STDOUT: %.555: type = fn_type_with_self_type %BB.type.64d, %B.facet.5e0 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .BitAnd = %Core.BitAnd +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.ad0 = import_ref Core//default, inst104 [no loc], unloaded +// CHECK:STDOUT: %Core.import_ref.08d: %BitAnd.assoc_type = import_ref Core//default, loc12_41, loaded [concrete = constants.%assoc0.a63] +// CHECK:STDOUT: %Core.Op = import_ref Core//default, Op, unloaded +// CHECK:STDOUT: %Core.import_ref.51c: = import_ref Core//default, loc15_36, loaded [symbolic = @impl.f92.%impl_witness (constants.%impl_witness.b81)] +// CHECK:STDOUT: %Core.import_ref.f6b058.1: type = import_ref Core//default, loc15_14, loaded [symbolic = @impl.f92.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.601: type = import_ref Core//default, loc15_24, loaded [symbolic = @impl.f92.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.9c1: type = import_ref Core//default, loc15_29, loaded [concrete = constants.%BitAnd.type] +// CHECK:STDOUT: %Core.import_ref.1e6: @impl.f92.%Op.type (%Op.type.f99) = import_ref Core//default, loc16_42, loaded [symbolic = @impl.f92.%Op (constants.%Op.05a)] +// CHECK:STDOUT: %Core.import_ref.f6b058.2: type = import_ref Core//default, loc15_14, loaded [symbolic = @impl.f92.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.040: %BitAnd.type = import_ref Core//default, inst104 [no loc], loaded [symbolic = constants.%Self.25f] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Empty = %Empty.decl +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Empty.decl: type = interface_decl @Empty [concrete = constants.%Empty.type] {} {} +// CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {} +// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @impl.d78 [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %Empty.ref: type = name_ref Empty, file.%Empty.decl [concrete = constants.%Empty.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc16: = impl_witness () [concrete = constants.%impl_witness.1bc] +// CHECK:STDOUT: impl_decl @impl.77d [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness (@impl.77d.%AA.decl) [concrete = constants.%impl_witness.97a] +// CHECK:STDOUT: impl_decl @impl.c94 [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc20: = impl_witness (@impl.c94.%BB.decl) [concrete = constants.%impl_witness.fe4] +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { +// CHECK:STDOUT: %T.patt.loc24_6.1: %facet_type.242 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc24_6.2 (constants.%T.patt.fd9)] +// CHECK:STDOUT: %T.param_patt: %facet_type.242 = value_param_pattern %T.patt.loc24_6.1, runtime_param [symbolic = %T.patt.loc24_6.2 (constants.%T.patt.fd9)] +// CHECK:STDOUT: %t.patt: @G.%T.as_type.loc24_28.2 (%T.as_type) = binding_pattern t +// CHECK:STDOUT: %t.param_patt: @G.%T.as_type.loc24_28.2 (%T.as_type) = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %facet_type.242 = value_param runtime_param +// CHECK:STDOUT: %.loc24_20.1: type = splice_block %.loc24_20.3 [concrete = constants.%facet_type.242] { +// CHECK:STDOUT: %A.ref.loc24: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %Empty.ref: type = name_ref Empty, file.%Empty.decl [concrete = constants.%Empty.type] +// CHECK:STDOUT: %impl.elem0.loc24_12: %.d4d = impl_witness_access constants.%impl_witness.3ea, element0 [concrete = constants.%Op.444] +// CHECK:STDOUT: %bound_method.loc24_12: = bound_method %A.ref.loc24, %impl.elem0.loc24_12 [concrete = constants.%Op.bound.6b1] +// CHECK:STDOUT: %specific_fn.loc24_12: = specific_function %bound_method.loc24_12, @Op.1(type) [concrete = constants.%Op.specific_fn.b4b] +// CHECK:STDOUT: %type.and.loc24_12: init type = call %specific_fn.loc24_12(%A.ref.loc24, %Empty.ref) [concrete = constants.%facet_type.d5f] +// CHECK:STDOUT: %B.ref.loc24: type = name_ref B, file.%B.decl [concrete = constants.%B.type] +// CHECK:STDOUT: %impl.elem0.loc24_20: %.d4d = impl_witness_access constants.%impl_witness.3ea, element0 [concrete = constants.%Op.444] +// CHECK:STDOUT: %bound_method.loc24_20: = bound_method %type.and.loc24_12, %impl.elem0.loc24_20 [concrete = constants.%Op.bound.b5b] +// CHECK:STDOUT: %specific_fn.loc24_20: = specific_function %bound_method.loc24_20, @Op.1(type) [concrete = constants.%Op.specific_fn.165] +// CHECK:STDOUT: %.loc24_12.1: type = value_of_initializer %type.and.loc24_12 [concrete = constants.%facet_type.d5f] +// CHECK:STDOUT: %.loc24_12.2: type = converted %type.and.loc24_12, %.loc24_12.1 [concrete = constants.%facet_type.d5f] +// CHECK:STDOUT: %type.and.loc24_20: init type = call %specific_fn.loc24_20(%.loc24_12.2, %B.ref.loc24) [concrete = constants.%facet_type.242] +// CHECK:STDOUT: %.loc24_20.2: type = value_of_initializer %type.and.loc24_20 [concrete = constants.%facet_type.242] +// CHECK:STDOUT: %.loc24_20.3: type = converted %type.and.loc24_20, %.loc24_20.2 [concrete = constants.%facet_type.242] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc24_6.1: %facet_type.242 = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %t.param: @G.%T.as_type.loc24_28.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc24_28.1: type = splice_block %.loc24_28.2 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref.loc24: %facet_type.242 = name_ref T, %T.loc24_6.1 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %T.as_type.loc24_28.1: type = facet_access_type %T.ref.loc24 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc24_28.2: type = converted %T.ref.loc24, %T.as_type.loc24_28.1 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @G.%T.as_type.loc24_28.2 (%T.as_type) = bind_name t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Empty { +// CHECK:STDOUT: %Self: %Empty.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.193] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .AA = +// CHECK:STDOUT: .BB = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @A { +// CHECK:STDOUT: %Self: %A.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.31d] +// CHECK:STDOUT: %AA.decl: %AA.type.b97 = fn_decl @AA.1 [concrete = constants.%AA.c3a] {} {} +// CHECK:STDOUT: %assoc0: %A.assoc_type = assoc_entity element0, %AA.decl [concrete = constants.%assoc0.f33] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .AA = %assoc0 +// CHECK:STDOUT: .BB = +// CHECK:STDOUT: witness = (%AA.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @B { +// CHECK:STDOUT: %Self: %B.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.783] +// CHECK:STDOUT: %BB.decl: %BB.type.64d = fn_decl @BB.1 [concrete = constants.%BB.11b] {} {} +// CHECK:STDOUT: %assoc0: %B.assoc_type = assoc_entity element0, %BB.decl [concrete = constants.%assoc0.019] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .BB = %assoc0 +// CHECK:STDOUT: .AA = +// CHECK:STDOUT: witness = (%BB.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @BitAnd [from "core.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Core.import_ref.ad0 +// CHECK:STDOUT: .Op = imports.%Core.import_ref.08d +// CHECK:STDOUT: witness = (imports.%Core.Op) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.d78: %C.ref as %Empty.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness.loc16 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.77d: %C.ref as %A.ref { +// CHECK:STDOUT: %AA.decl: %AA.type.c29 = fn_decl @AA.2 [concrete = constants.%AA.95d] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .AA = %AA.decl +// CHECK:STDOUT: witness = file.%impl_witness.loc17 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.c94: %C.ref as %B.ref { +// CHECK:STDOUT: %BB.decl: %BB.type.24d = fn_decl @BB.2 [concrete = constants.%BB.fe8] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .BB = %BB.decl +// CHECK:STDOUT: witness = file.%impl_witness.loc20 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @impl.f92(imports.%Core.import_ref.f6b058.1: type) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt.e01)] +// CHECK:STDOUT: %impl_witness: = impl_witness (imports.%Core.import_ref.1e6), @impl.f92(%T) [symbolic = %impl_witness (constants.%impl_witness.db8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Op.type: type = fn_type @Op.1, @impl.f92(%T) [symbolic = %Op.type (constants.%Op.type.f99)] +// CHECK:STDOUT: %Op: @impl.f92.%Op.type (%Op.type.f99) = struct_value () [symbolic = %Op (constants.%Op.05a)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.f92.%T (%T.8b3) [symbolic = %require_complete (constants.%require_complete.4ae)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Core.import_ref.601 as imports.%Core.import_ref.9c1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Core.import_ref.51c +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AA.1(@A.%Self: %A.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @BB.1(@B.%Self: %B.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AA.2() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @BB.2() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Op.1(imports.%Core.import_ref.f6b058.2: type) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Op.1.%T (%T.8b3)](%other.param_patt: @Op.1.%T (%T.8b3)) -> @Op.1.%T (%T.8b3) = "type.and"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Op.2(imports.%Core.import_ref.040: %BitAnd.type) [from "core.carbon"] { +// CHECK:STDOUT: %Self: %BitAnd.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.25f)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Op.2.%Self.as_type (%Self.as_type)](%other.param_patt: @Op.2.%Self.as_type (%Self.as_type)) -> @Op.2.%Self.as_type (%Self.as_type); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @G(%T.loc24_6.1: %facet_type.242) { +// CHECK:STDOUT: %T.loc24_6.2: %facet_type.242 = bind_symbolic_name T, 0 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %T.patt.loc24_6.2: %facet_type.242 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc24_6.2 (constants.%T.patt.fd9)] +// CHECK:STDOUT: %T.as_type.loc24_28.2: type = facet_access_type %T.loc24_6.2 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @G.%T.as_type.loc24_28.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete.383)] +// CHECK:STDOUT: %T.as_wit.loc25_4.2: = facet_access_witness %T.loc24_6.2 [symbolic = %T.as_wit.loc25_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %A.facet: %A.type = facet_value %T.as_type.loc24_28.2, %T.as_wit.loc25_4.2 [symbolic = %A.facet (constants.%A.facet.d6d)] +// CHECK:STDOUT: %.loc25_4.2: type = fn_type_with_self_type constants.%AA.type.b97, %A.facet [symbolic = %.loc25_4.2 (constants.%.124)] +// CHECK:STDOUT: %impl.elem0.loc25_4.2: @G.%.loc25_4.2 (%.124) = impl_witness_access %T.as_wit.loc25_4.2, element0 [symbolic = %impl.elem0.loc25_4.2 (constants.%impl.elem0.2b1)] +// CHECK:STDOUT: %specific_fn.loc25_4.2: = specific_function %impl.elem0.loc25_4.2, @AA.1(%A.facet) [symbolic = %specific_fn.loc25_4.2 (constants.%specific_fn.80f)] +// CHECK:STDOUT: %B.facet: %B.type = facet_value %T.as_type.loc24_28.2, %T.as_wit.loc25_4.2 [symbolic = %B.facet (constants.%B.facet.1c2)] +// CHECK:STDOUT: %.loc26_4.2: type = fn_type_with_self_type constants.%BB.type.64d, %B.facet [symbolic = %.loc26_4.2 (constants.%.e3a)] +// CHECK:STDOUT: %impl.elem0.loc26_4.2: @G.%.loc26_4.2 (%.e3a) = impl_witness_access %T.as_wit.loc25_4.2, element0 [symbolic = %impl.elem0.loc26_4.2 (constants.%impl.elem0.f5b)] +// CHECK:STDOUT: %specific_fn.loc26_4.2: = specific_function %impl.elem0.loc26_4.2, @BB.1(%B.facet) [symbolic = %specific_fn.loc26_4.2 (constants.%specific_fn.62f)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %facet_type.242](%t.param_patt: @G.%T.as_type.loc24_28.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %t.ref.loc25: @G.%T.as_type.loc24_28.2 (%T.as_type) = name_ref t, %t +// CHECK:STDOUT: %AA.ref.loc25: %A.assoc_type = name_ref AA, @A.%assoc0 [concrete = constants.%assoc0.f33] +// CHECK:STDOUT: %T.as_type.loc25: type = facet_access_type constants.%T.2df [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc25_4.1: type = converted constants.%T.2df, %T.as_type.loc25 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc25_4.1: = facet_access_witness constants.%T.2df [symbolic = %T.as_wit.loc25_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc25_4.1: @G.%.loc25_4.2 (%.124) = impl_witness_access %T.as_wit.loc25_4.1, element0 [symbolic = %impl.elem0.loc25_4.2 (constants.%impl.elem0.2b1)] +// CHECK:STDOUT: %specific_fn.loc25_4.1: = specific_function %impl.elem0.loc25_4.1, @AA.1(constants.%A.facet.d6d) [symbolic = %specific_fn.loc25_4.2 (constants.%specific_fn.80f)] +// CHECK:STDOUT: %AA.call.loc25: init %empty_tuple.type = call %specific_fn.loc25_4.1() +// CHECK:STDOUT: %t.ref.loc26: @G.%T.as_type.loc24_28.2 (%T.as_type) = name_ref t, %t +// CHECK:STDOUT: %BB.ref.loc26: %B.assoc_type = name_ref BB, @B.%assoc0 [concrete = constants.%assoc0.019] +// CHECK:STDOUT: %T.as_type.loc26: type = facet_access_type constants.%T.2df [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc26_4.1: type = converted constants.%T.2df, %T.as_type.loc26 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc26: = facet_access_witness constants.%T.2df [symbolic = %T.as_wit.loc25_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc26_4.1: @G.%.loc26_4.2 (%.e3a) = impl_witness_access %T.as_wit.loc26, element0 [symbolic = %impl.elem0.loc26_4.2 (constants.%impl.elem0.f5b)] +// CHECK:STDOUT: %specific_fn.loc26_4.1: = specific_function %impl.elem0.loc26_4.1, @BB.1(constants.%B.facet.1c2) [symbolic = %specific_fn.loc26_4.2 (constants.%specific_fn.62f)] +// CHECK:STDOUT: %BB.call.loc26: init %empty_tuple.type = call %specific_fn.loc26_4.1() +// CHECK:STDOUT: %T.ref.loc28: %facet_type.242 = name_ref T, %T.loc24_6.1 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %AA.ref.loc28: %A.assoc_type = name_ref AA, @A.%assoc0 [concrete = constants.%assoc0.f33] +// CHECK:STDOUT: %T.as_type.loc28: type = facet_access_type %T.ref.loc28 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc28: type = converted %T.ref.loc28, %T.as_type.loc28 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc28: = facet_access_witness %T.ref.loc28 [symbolic = %T.as_wit.loc25_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc28: @G.%.loc25_4.2 (%.124) = impl_witness_access %T.as_wit.loc28, element0 [symbolic = %impl.elem0.loc25_4.2 (constants.%impl.elem0.2b1)] +// CHECK:STDOUT: %specific_fn.loc28: = specific_function %impl.elem0.loc28, @AA.1(constants.%A.facet.d6d) [symbolic = %specific_fn.loc25_4.2 (constants.%specific_fn.80f)] +// CHECK:STDOUT: %AA.call.loc28: init %empty_tuple.type = call %specific_fn.loc28() +// CHECK:STDOUT: %T.ref.loc29: %facet_type.242 = name_ref T, %T.loc24_6.1 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %BB.ref.loc29: %B.assoc_type = name_ref BB, @B.%assoc0 [concrete = constants.%assoc0.019] +// CHECK:STDOUT: %T.as_type.loc29: type = facet_access_type %T.ref.loc29 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc29: type = converted %T.ref.loc29, %T.as_type.loc29 [symbolic = %T.as_type.loc24_28.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc29: = facet_access_witness %T.ref.loc29 [symbolic = %T.as_wit.loc25_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc29: @G.%.loc26_4.2 (%.e3a) = impl_witness_access %T.as_wit.loc29, element0 [symbolic = %impl.elem0.loc26_4.2 (constants.%impl.elem0.f5b)] +// CHECK:STDOUT: %specific_fn.loc29: = specific_function %impl.elem0.loc29, @BB.1(constants.%B.facet.1c2) [symbolic = %specific_fn.loc26_4.2 (constants.%specific_fn.62f)] +// CHECK:STDOUT: %BB.call.loc29: init %empty_tuple.type = call %specific_fn.loc29() +// CHECK:STDOUT: %T.ref.loc38: %facet_type.242 = name_ref T, %T.loc24_6.1 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %A.ref.loc38: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %AA.ref.loc38: %A.assoc_type = name_ref AA, @A.%assoc0 [concrete = constants.%assoc0.f33] +// CHECK:STDOUT: %T.ref.loc46: %facet_type.242 = name_ref T, %T.loc24_6.1 [symbolic = %T.loc24_6.2 (constants.%T.2df)] +// CHECK:STDOUT: %B.ref.loc46: type = name_ref B, file.%B.decl [concrete = constants.%B.type] +// CHECK:STDOUT: %BB.ref.loc46: %B.assoc_type = name_ref BB, @B.%assoc0 [concrete = constants.%assoc0.019] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %G.ref: %G.type = name_ref G, file.%G.decl [concrete = constants.%G] +// CHECK:STDOUT: %.loc61_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc61_6.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc61_6.3: init %C = class_init (), %.loc61_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc61_6.4: ref %C = temporary %.loc61_6.2, %.loc61_6.3 +// CHECK:STDOUT: %.loc61_8.1: ref %C = converted %.loc61_6.1, %.loc61_6.4 +// CHECK:STDOUT: %facet_value.loc61_12.1: %facet_type.242 = facet_value constants.%C, constants.%impl_witness.1bc [concrete = constants.%facet_value] +// CHECK:STDOUT: %.loc61_12.1: %facet_type.242 = converted constants.%C, %facet_value.loc61_12.1 [concrete = constants.%facet_value] +// CHECK:STDOUT: %facet_value.loc61_12.2: %facet_type.242 = facet_value constants.%C, constants.%impl_witness.1bc [concrete = constants.%facet_value] +// CHECK:STDOUT: %.loc61_12.2: %facet_type.242 = converted constants.%C, %facet_value.loc61_12.2 [concrete = constants.%facet_value] +// CHECK:STDOUT: %G.specific_fn: = specific_function %G.ref, @G(constants.%facet_value) [concrete = constants.%G.specific_fn] +// CHECK:STDOUT: %.loc61_8.2: %C = bind_value %.loc61_8.1 +// CHECK:STDOUT: %G.call: init %empty_tuple.type = call %G.specific_fn(%.loc61_8.2) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AA.1(constants.%Self.31d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @BB.1(constants.%Self.783) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AA.1(constants.%A.facet.afe) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @BB.1(constants.%B.facet.3a2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl.f92(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %T.patt => constants.%T.8b3 +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.db8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl.f92(%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.1(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl.f92(type) { +// CHECK:STDOUT: %T => type +// CHECK:STDOUT: %T.patt => type +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.3ea +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Op.type => constants.%Op.type.eb8 +// CHECK:STDOUT: %Op => constants.%Op.444 +// CHECK:STDOUT: %require_complete => constants.%complete_type.473 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.2(constants.%Self.25f) { +// CHECK:STDOUT: %Self => constants.%Self.25f +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Op.1(type) { +// CHECK:STDOUT: %T => type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @G(constants.%T.2df) { +// CHECK:STDOUT: %T.loc24_6.2 => constants.%T.2df +// CHECK:STDOUT: %T.patt.loc24_6.2 => constants.%T.2df +// CHECK:STDOUT: %T.as_type.loc24_28.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AA.1(constants.%A.facet.d6d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @BB.1(constants.%B.facet.1c2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AA.1(@G.%A.facet) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @BB.1(@G.%B.facet) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @G(constants.%facet_value) { +// CHECK:STDOUT: %T.loc24_6.2 => constants.%facet_value +// CHECK:STDOUT: %T.patt.loc24_6.2 => constants.%facet_value +// CHECK:STDOUT: %T.as_type.loc24_28.2 => constants.%C +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %T.as_wit.loc25_4.2 => constants.%impl_witness.1bc +// CHECK:STDOUT: %A.facet => constants.%A.facet.beb +// CHECK:STDOUT: %.loc25_4.2 => constants.%.778 +// CHECK:STDOUT: %impl.elem0.loc25_4.2 => +// CHECK:STDOUT: %specific_fn.loc25_4.2 => +// CHECK:STDOUT: %B.facet => constants.%B.facet.5e0 +// CHECK:STDOUT: %.loc26_4.2 => constants.%.555 +// CHECK:STDOUT: %impl.elem0.loc26_4.2 => +// CHECK:STDOUT: %specific_fn.loc26_4.2 => +// CHECK:STDOUT: } +// CHECK:STDOUT: From fbb702bf037b7be700adc51c0d9530a391d692ea Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 13:01:05 -0500 Subject: [PATCH 15/21] less-other-requirements --- toolchain/check/impl_lookup.cpp | 74 +++++++++++++-------------------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index a66733976b2c7..59fbdc7583cd9 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -160,9 +160,9 @@ static auto FindAndDiagnoseImplLookupCycle( // Gets the set of `SpecificInterface`s that are required by a facet type // (as a constant value). static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, - SemIR::ConstantId interface_const_id) - -> llvm::SmallVector< - std::pair, 16> { + SemIR::ConstantId interface_const_id, + bool& has_other_requirements) + -> llvm::SmallVector { // The `interface_const_id` is a constant value for some facet type. We do // this long chain of steps to go from that constant value to the // `FacetTypeId` found on the `FacetType` instruction of this constant value, @@ -181,9 +181,9 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, const auto& complete_facet_type = context.complete_facet_types().Get(complete_facet_type_id); - llvm::SmallVector< - std::pair, 16> + llvm::SmallVector interface_ids; + has_other_requirements = false; if (complete_facet_type.required_interfaces.empty()) { // This should never happen - a FacetType either requires or is bounded by @@ -195,19 +195,18 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, return interface_ids; } for (auto required : complete_facet_type.required_interfaces) { - interface_ids.push_back( - {required, - context.facet_types().Get(facet_type_id).other_requirements}); + interface_ids.push_back(required); + if (context.facet_types().Get(facet_type_id).other_requirements) { + has_other_requirements = true; + } } return interface_ids; } static auto GetWitnessIdForImpl( Context& context, SemIR::LocId loc_id, SemIR::ConstantId type_const_id, - SemIR::ConstantId interface_const_id, const SemIR::CompleteFacetType::RequiredInterface& interface, - bool interface_has_other_requirements, const SemIR::Impl& impl) - -> SemIR::InstId { + const SemIR::Impl& impl) -> SemIR::InstId { // If the impl's interface_id differs from the query, then this impl can not // possibly provide the queried interface, and we don't need to proceed. if (impl.interface.interface_id != interface.interface_id) { @@ -268,34 +267,15 @@ static auto GetWitnessIdForImpl( return SemIR::InstId::None; } - auto deduced_constaint_facet_type_id = - context.insts() - .GetAs(deduced_constraint_id) - .facet_type_id; - bool constraint_has_other_requirements = - context.facet_types() - .Get(deduced_constaint_facet_type_id) - .other_requirements; - - // If there are requirements on the impl's constraint facet type, or on the - // query facet type, that are not modelled yet in the FacetTypeInfo and - // CompleteFacetType, then we can't tell if we have a match for this specific - // query interface. - // - // In this case we just do the wrong thing if the either the constraint or - // query facet type had more than one interface in it, and compare the - // constant value of the entire query facet type against the entire impl's - // constraint facet type. The latter will include those other requirements - // (correctly), but the former may include more things unrelated to this one - // interface being looked for here and thus fail incorrectly. - // - // TODO: Stop using `other_requirements` and look at `where .Self impls` - // clauses with further impl lookups as needed. These should become part of - // the set of interfaces for which this function is called on, and this - // function shouldn't have to think about them. - if (constraint_has_other_requirements || interface_has_other_requirements) { - if (context.constant_values().Get(deduced_constraint_id) != - interface_const_id) { + { + auto deduced_constaint_facet_type_id = + context.insts() + .GetAs(deduced_constraint_id) + .facet_type_id; + if (context.facet_types() + .Get(deduced_constaint_facet_type_id) + .other_requirements) { + // TODO: Remove this when other requirements goes away. return SemIR::InstId::None; } } @@ -336,13 +316,18 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, return SemIR::ErrorInst::SingletonInstId; } - auto interfaces = - GetInterfacesFromConstantId(context, loc_id, interface_const_id); + bool has_other_requirements = false; + auto interfaces = GetInterfacesFromConstantId( + context, loc_id, interface_const_id, has_other_requirements); if (interfaces.empty()) { // TODO: Remove this when the context.TODO() is removed in // GetInterfacesFromConstantId. return SemIR::InstId::None; } + if (has_other_requirements) { + // TODO: Remove this when other requirements go away. + return SemIR::InstId::None; + } llvm::SmallVector result_witness_ids; @@ -354,13 +339,12 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id, // We need to find a witness for each interface in `interfaces`. We return // them in the same order as they are found in the `CompleteFacetType`, which // is the same order as in `interfaces` here. - for (const auto& [interface, interface_has_other_requirements] : interfaces) { + for (const auto& interface : interfaces) { bool found_witness = false; for (const auto& impl : context.impls().array_ref()) { stack.back().impl_loc = impl.definition_id; - auto result_witness_id = GetWitnessIdForImpl( - context, loc_id, type_const_id, interface_const_id, interface, - interface_has_other_requirements, impl); + auto result_witness_id = + GetWitnessIdForImpl(context, loc_id, type_const_id, interface, impl); if (result_witness_id.has_value()) { result_witness_ids.push_back(result_witness_id); // We found a matching impl; don't keep looking for this `interface`, From 9d771295ae7df043358010b1f6433750b43a12f6 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 13:01:17 -0500 Subject: [PATCH 16/21] format --- toolchain/check/testdata/facet/no_prelude/combine.carbon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolchain/check/testdata/facet/no_prelude/combine.carbon b/toolchain/check/testdata/facet/no_prelude/combine.carbon index 8a80284876c77..5130565aaf832 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine.carbon +++ b/toolchain/check/testdata/facet/no_prelude/combine.carbon @@ -105,7 +105,7 @@ fn F() { // CHECK:STDERR: ^~~~~ // CHECK:STDERR: ({} as C) as (C as (A & A)); - + AA({} as C); } From 0be78b268eff01987a0c1b1d7a5626b8d76b5429 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 13:13:11 -0500 Subject: [PATCH 17/21] rename-test-to-fail --- ...il_todo_call_combined_impl_witness.carbon} | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) rename toolchain/check/testdata/facet/no_prelude/{combine_witness.carbon => fail_todo_call_combined_impl_witness.carbon} (97%) diff --git a/toolchain/check/testdata/facet/no_prelude/combine_witness.carbon b/toolchain/check/testdata/facet/no_prelude/fail_todo_call_combined_impl_witness.carbon similarity index 97% rename from toolchain/check/testdata/facet/no_prelude/combine_witness.carbon rename to toolchain/check/testdata/facet/no_prelude/fail_todo_call_combined_impl_witness.carbon index 2a1524601f3ca..383870afecb1c 100644 --- a/toolchain/check/testdata/facet/no_prelude/combine_witness.carbon +++ b/toolchain/check/testdata/facet/no_prelude/fail_todo_call_combined_impl_witness.carbon @@ -4,9 +4,9 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/no_prelude/combine_witness.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/no_prelude/fail_todo_call_combined_impl_witness.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/no_prelude/combine_witness.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/no_prelude/fail_todo_call_combined_impl_witness.carbon // --- core.carbon package Core; @@ -27,7 +27,7 @@ impl forall [T:! type] T as BitAnd { fn Op[self: Self](other: Self) -> Self = "type.and"; } -// --- call_combined_impl_witness.carbon +// --- fail_todo_call_combined_impl_witness.carbon library "[[@TEST_NAME]]"; @@ -61,30 +61,30 @@ fn G[T:! A & Empty & B](t: T) { // TODO: Qualified lookup of `AA` and `BB` should also be possible here, using // the witnesses found in type deduction. - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE+4]]:3: error: cannot access member of interface `A` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: T.(A.AA)(); // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: T.(A.AA)(); - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+7]]:3: error: cannot access member of interface `B` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE+7]]:3: error: cannot access member of interface `B` in type `Empty & A & B` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: T.(B.BB)(); // CHECK:STDERR: ^~~~~~~~ // CHECK:STDERR: - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE-18]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE-18]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] // CHECK:STDERR: t.AA(); // CHECK:STDERR: ^~~~ T.(B.BB)(); } fn F() { - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+11]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE+11]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] // CHECK:STDERR: G({} as C); // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE-28]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE-28]]:3: error: semantics TODO: `incorrect witness for multiple interfaces in a facet type` [SemanticsTodo] // CHECK:STDERR: t.BB(); // CHECK:STDERR: ^~~~ - // CHECK:STDERR: call_combined_impl_witness.carbon:[[@LINE+4]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] + // CHECK:STDERR: fail_todo_call_combined_impl_witness.carbon:[[@LINE+4]]:3: note: in `G(C as Empty & A & B)` used here [ResolvingSpecificHere] // CHECK:STDERR: G({} as C); // CHECK:STDERR: ^ // CHECK:STDERR: @@ -408,7 +408,7 @@ fn F() { // CHECK:STDOUT: %Self.as_type.loc12_15.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- call_combined_impl_witness.carbon +// CHECK:STDOUT: --- fail_todo_call_combined_impl_witness.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Empty.type: type = facet_type <@Empty> [concrete] From 638404464d851e2db62bbd7c81581e9aa85878b1 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 14:03:51 -0500 Subject: [PATCH 18/21] move-out-of-loop --- toolchain/check/impl_lookup.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 59fbdc7583cd9..c746e4ba2a515 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -181,9 +181,11 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, const auto& complete_facet_type = context.complete_facet_types().Get(complete_facet_type_id); + has_other_requirements = + context.facet_types().Get(facet_type_id).other_requirements; + llvm::SmallVector interface_ids; - has_other_requirements = false; if (complete_facet_type.required_interfaces.empty()) { // This should never happen - a FacetType either requires or is bounded by @@ -196,9 +198,6 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, } for (auto required : complete_facet_type.required_interfaces) { interface_ids.push_back(required); - if (context.facet_types().Get(facet_type_id).other_requirements) { - has_other_requirements = true; - } } return interface_ids; } From 1b8c648f21fd950ecb0405d4b9d47f4c54008cd9 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 14:08:26 -0500 Subject: [PATCH 19/21] no-16 --- toolchain/check/impl_lookup.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index c746e4ba2a515..d3e801b5f211c 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -162,7 +162,7 @@ static auto FindAndDiagnoseImplLookupCycle( static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, SemIR::ConstantId interface_const_id, bool& has_other_requirements) - -> llvm::SmallVector { + -> llvm::SmallVector { // The `interface_const_id` is a constant value for some facet type. We do // this long chain of steps to go from that constant value to the // `FacetTypeId` found on the `FacetType` instruction of this constant value, @@ -184,9 +184,6 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, has_other_requirements = context.facet_types().Get(facet_type_id).other_requirements; - llvm::SmallVector - interface_ids; - if (complete_facet_type.required_interfaces.empty()) { // This should never happen - a FacetType either requires or is bounded by // some `.Self impls` clause. Otherwise you would just have `type` (aka @@ -194,12 +191,9 @@ static auto GetInterfacesFromConstantId(Context& context, SemIR::LocId loc_id, context.TODO(loc_id, "impl lookup for a FacetType with no interface (using " "`where .Self impls ...` instead?)"); - return interface_ids; - } - for (auto required : complete_facet_type.required_interfaces) { - interface_ids.push_back(required); + return {}; } - return interface_ids; + return complete_facet_type.required_interfaces; } static auto GetWitnessIdForImpl( From 6bc28e14fdbda8d7f6693908d55b01fb3754742a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 4 Mar 2025 15:25:10 -0500 Subject: [PATCH 20/21] Update toolchain/check/impl_lookup.cpp Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com> --- toolchain/check/impl_lookup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index d3e801b5f211c..a3fb381eca610 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -261,12 +261,12 @@ static auto GetWitnessIdForImpl( } { - auto deduced_constaint_facet_type_id = + auto deduced_constraint_facet_type_id = context.insts() .GetAs(deduced_constraint_id) .facet_type_id; if (context.facet_types() - .Get(deduced_constaint_facet_type_id) + .Get(deduced_constraint_facet_type_id) .other_requirements) { // TODO: Remove this when other requirements goes away. return SemIR::InstId::None; From 62dbf0d81299a1d64e7b29bb47ab88b89f888705 Mon Sep 17 00:00:00 2001 From: danakj Date: Tue, 4 Mar 2025 16:00:09 -0500 Subject: [PATCH 21/21] compare-specifics --- toolchain/check/impl_lookup.cpp | 35 +- ..._value_to_generic_facet_value_value.carbon | 1125 +++++++++++++++-- 2 files changed, 1054 insertions(+), 106 deletions(-) diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index a3fb381eca610..a6f13213797e5 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -260,17 +260,30 @@ static auto GetWitnessIdForImpl( return SemIR::InstId::None; } - { - auto deduced_constraint_facet_type_id = - context.insts() - .GetAs(deduced_constraint_id) - .facet_type_id; - if (context.facet_types() - .Get(deduced_constraint_facet_type_id) - .other_requirements) { - // TODO: Remove this when other requirements goes away. - return SemIR::InstId::None; - } + auto deduced_constraint_facet_type_id = + context.insts() + .GetAs(deduced_constraint_id) + .facet_type_id; + const auto& deduced_constraint_complete_facet_type = + context.complete_facet_types().Get( + context.complete_facet_types().TryGetId( + deduced_constraint_facet_type_id)); + CARBON_CHECK(deduced_constraint_complete_facet_type.num_to_impl == 1); + + if (context.facet_types() + .Get(deduced_constraint_facet_type_id) + .other_requirements) { + // TODO: Remove this when other requirements goes away. + return SemIR::InstId::None; + } + + // The specifics in the queried interface must match the deduced specifics in + // the impl's constraint facet type. + auto impl_interface_specific_id = + deduced_constraint_complete_facet_type.required_interfaces[0].specific_id; + auto query_interface_specific_id = interface.specific_id; + if (impl_interface_specific_id != query_interface_specific_id) { + return SemIR::InstId::None; } LoadImportRef(context, impl.witness_id); diff --git a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon index bc6eb0297b6b9..27e61f325fbc5 100644 --- a/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon @@ -33,12 +33,83 @@ impl ImplsGeneric as Generic(GenericParam) { fn F() {} } -fn CallGenericMethod2[T:! type, U:! Generic(T)](a: U, s: T) { +fn CallGenericMethod[T:! type, U:! Generic(T)](a: U, s: T) { U.F(); } fn G() { - CallGenericMethod2({} as ImplsGeneric, {} as GenericParam); + CallGenericMethod({} as ImplsGeneric, {} as GenericParam); +} + +// --- multiple_generic_params_one_fixed_one_deduced.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface I(V:! type, W:! type) {} + +class C {} + +impl forall [T:! type] C as I(T, ()) {} + +fn A[T:! I({}, ())](t: T) {} + +fn B() { + A({} as C); +} + +// --- fail_mismatch_impl_constraint_with_fixed_specific.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface I(V:! type, W:! type) {} + +class C {} + +impl forall [T:! type] C as I(T, ()) {} + +fn A[T:! I({}, {})](t: T) {} + +fn B() { + // CHECK:STDERR: fail_mismatch_impl_constraint_with_fixed_specific.carbon:[[@LINE+10]]:3: error: cannot implicitly convert value of type `type` to `I({}, {})` [ImplicitAsConversionFailure] + // CHECK:STDERR: A({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_mismatch_impl_constraint_with_fixed_specific.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(I({}, {}))` [MissingImplInMemberAccessNote] + // CHECK:STDERR: A({} as C); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: fail_mismatch_impl_constraint_with_fixed_specific.carbon:[[@LINE-9]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn A[T:! I({}, {})](t: T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + A({} as C); +} + +// --- fail_mismatch_impl_self_with_fixed_specific.carbon +library "[[@TEST_NAME]]"; + +import Core; + +interface I {} + +class C(V:! type, W:! type) {} + +impl forall [T:! type] C(T, ()) as I {} + +fn A[T:! I](t: T) {} + +fn B() { + // CHECK:STDERR: fail_mismatch_impl_self_with_fixed_specific.carbon:[[@LINE+10]]:3: error: cannot implicitly convert value of type `type` to `I` [ImplicitAsConversionFailure] + // CHECK:STDERR: A({} as C({}, {})); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_mismatch_impl_self_with_fixed_specific.carbon:[[@LINE+7]]:3: note: type `type` does not implement interface `Core.ImplicitAs(I)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: A({} as C({}, {})); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_mismatch_impl_self_with_fixed_specific.carbon:[[@LINE-9]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn A[T:! I](t: T) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + A({} as C({}, {})); } // CHECK:STDOUT: --- core.carbon @@ -170,8 +241,8 @@ fn G() { // CHECK:STDOUT: %U: %Generic.type.91ccba.2 = bind_symbolic_name U, 1 [symbolic] // CHECK:STDOUT: %U.patt: %Generic.type.91ccba.2 = symbolic_binding_pattern U, 1 [symbolic] // CHECK:STDOUT: %U.as_type: type = facet_access_type %U [symbolic] -// CHECK:STDOUT: %CallGenericMethod2.type: type = fn_type @CallGenericMethod2 [concrete] -// CHECK:STDOUT: %CallGenericMethod2: %CallGenericMethod2.type = struct_value () [concrete] +// CHECK:STDOUT: %CallGenericMethod.type: type = fn_type @CallGenericMethod [concrete] +// CHECK:STDOUT: %CallGenericMethod: %CallGenericMethod.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.7b2: = require_complete_type %U.as_type [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %F.type.f439a9.2: type = fn_type @F.1, @Generic(%T) [symbolic] @@ -188,7 +259,7 @@ fn G() { // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %ImplsGeneric.val: %ImplsGeneric = struct_value () [concrete] // CHECK:STDOUT: %GenericParam.val: %GenericParam = struct_value () [concrete] -// CHECK:STDOUT: %CallGenericMethod2.specific_fn: = specific_function %CallGenericMethod2, @CallGenericMethod2(%GenericParam, %Generic.facet.b0a) [concrete] +// CHECK:STDOUT: %CallGenericMethod.specific_fn: = specific_function %CallGenericMethod, @CallGenericMethod(%GenericParam, %Generic.facet.b0a) [concrete] // CHECK:STDOUT: %complete_type.997: = complete_type_witness %Generic.type.769 [concrete] // CHECK:STDOUT: %.db1: type = fn_type_with_self_type %F.type.4cf, %Generic.facet.b0a [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F.a56, @F.1(%GenericParam, %Generic.facet.b0a) [concrete] @@ -206,7 +277,7 @@ fn G() { // CHECK:STDOUT: .Generic = %Generic.decl // CHECK:STDOUT: .GenericParam = %GenericParam.decl // CHECK:STDOUT: .ImplsGeneric = %ImplsGeneric.decl -// CHECK:STDOUT: .CallGenericMethod2 = %CallGenericMethod2.decl +// CHECK:STDOUT: .CallGenericMethod = %CallGenericMethod.decl // CHECK:STDOUT: .G = %G.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core @@ -226,35 +297,35 @@ fn G() { // CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%F.decl) [concrete = constants.%impl_witness] -// CHECK:STDOUT: %CallGenericMethod2.decl: %CallGenericMethod2.type = fn_decl @CallGenericMethod2 [concrete = constants.%CallGenericMethod2] { -// CHECK:STDOUT: %T.patt.loc17_23.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_23.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc17_23.1, runtime_param [symbolic = %T.patt.loc17_23.2 (constants.%T.patt)] -// CHECK:STDOUT: %U.patt.loc17_33.1: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_33.2 (constants.%U.patt)] -// CHECK:STDOUT: %U.param_patt: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = value_param_pattern %U.patt.loc17_33.1, runtime_param [symbolic = %U.patt.loc17_33.2 (constants.%U.patt)] -// CHECK:STDOUT: %a.patt: @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type) = binding_pattern a -// CHECK:STDOUT: %a.param_patt: @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type) = value_param_pattern %a.patt, runtime_param0 -// CHECK:STDOUT: %s.patt: @CallGenericMethod2.%T.loc17_23.2 (%T) = binding_pattern s -// CHECK:STDOUT: %s.param_patt: @CallGenericMethod2.%T.loc17_23.2 (%T) = value_param_pattern %s.patt, runtime_param1 +// CHECK:STDOUT: %CallGenericMethod.decl: %CallGenericMethod.type = fn_decl @CallGenericMethod [concrete = constants.%CallGenericMethod] { +// CHECK:STDOUT: %T.patt.loc17_22.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_22.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc17_22.1, runtime_param [symbolic = %T.patt.loc17_22.2 (constants.%T.patt)] +// CHECK:STDOUT: %U.patt.loc17_32.1: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_32.2 (constants.%U.patt)] +// CHECK:STDOUT: %U.param_patt: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = value_param_pattern %U.patt.loc17_32.1, runtime_param [symbolic = %U.patt.loc17_32.2 (constants.%U.patt)] +// CHECK:STDOUT: %a.patt: @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type) = binding_pattern a +// CHECK:STDOUT: %a.param_patt: @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type) = value_param_pattern %a.patt, runtime_param0 +// CHECK:STDOUT: %s.patt: @CallGenericMethod.%T.loc17_22.2 (%T) = binding_pattern s +// CHECK:STDOUT: %s.param_patt: @CallGenericMethod.%T.loc17_22.2 (%T) = value_param_pattern %s.patt, runtime_param1 // CHECK:STDOUT: } { // CHECK:STDOUT: %T.param: type = value_param runtime_param -// CHECK:STDOUT: %T.loc17_23.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc17_23.2 (constants.%T)] -// CHECK:STDOUT: %U.param: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = value_param runtime_param -// CHECK:STDOUT: %.loc17_46: type = splice_block %Generic.type.loc17_46.1 [symbolic = %Generic.type.loc17_46.2 (constants.%Generic.type.91ccba.2)] { +// CHECK:STDOUT: %T.loc17_22.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc17_22.2 (constants.%T)] +// CHECK:STDOUT: %U.param: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = value_param runtime_param +// CHECK:STDOUT: %.loc17_45: type = splice_block %Generic.type.loc17_45.1 [symbolic = %Generic.type.loc17_45.2 (constants.%Generic.type.91ccba.2)] { // CHECK:STDOUT: %Generic.ref: %Generic.type.c21 = name_ref Generic, file.%Generic.decl [concrete = constants.%Generic.generic] -// CHECK:STDOUT: %T.ref.loc17_45: type = name_ref T, %T.loc17_23.1 [symbolic = %T.loc17_23.2 (constants.%T)] -// CHECK:STDOUT: %Generic.type.loc17_46.1: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc17_46.2 (constants.%Generic.type.91ccba.2)] +// CHECK:STDOUT: %T.ref.loc17_44: type = name_ref T, %T.loc17_22.1 [symbolic = %T.loc17_22.2 (constants.%T)] +// CHECK:STDOUT: %Generic.type.loc17_45.1: type = facet_type <@Generic, @Generic(constants.%T)> [symbolic = %Generic.type.loc17_45.2 (constants.%Generic.type.91ccba.2)] // CHECK:STDOUT: } -// CHECK:STDOUT: %U.loc17_33.1: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc17_33.2 (constants.%U)] -// CHECK:STDOUT: %a.param: @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type) = value_param runtime_param0 -// CHECK:STDOUT: %.loc17_52.1: type = splice_block %.loc17_52.2 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] { -// CHECK:STDOUT: %U.ref.loc17: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = name_ref U, %U.loc17_33.1 [symbolic = %U.loc17_33.2 (constants.%U)] -// CHECK:STDOUT: %U.as_type.loc17_52.1: type = facet_access_type %U.ref.loc17 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] -// CHECK:STDOUT: %.loc17_52.2: type = converted %U.ref.loc17, %U.as_type.loc17_52.1 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] +// CHECK:STDOUT: %U.loc17_32.1: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = bind_symbolic_name U, 1, %U.param [symbolic = %U.loc17_32.2 (constants.%U)] +// CHECK:STDOUT: %a.param: @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc17_51.1: type = splice_block %.loc17_51.2 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] { +// CHECK:STDOUT: %U.ref.loc17: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = name_ref U, %U.loc17_32.1 [symbolic = %U.loc17_32.2 (constants.%U)] +// CHECK:STDOUT: %U.as_type.loc17_51.1: type = facet_access_type %U.ref.loc17 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] +// CHECK:STDOUT: %.loc17_51.2: type = converted %U.ref.loc17, %U.as_type.loc17_51.1 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type) = bind_name a, %a.param -// CHECK:STDOUT: %s.param: @CallGenericMethod2.%T.loc17_23.2 (%T) = value_param runtime_param1 -// CHECK:STDOUT: %T.ref.loc17_58: type = name_ref T, %T.loc17_23.1 [symbolic = %T.loc17_23.2 (constants.%T)] -// CHECK:STDOUT: %s: @CallGenericMethod2.%T.loc17_23.2 (%T) = bind_name s, %s.param +// CHECK:STDOUT: %a: @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type) = bind_name a, %a.param +// CHECK:STDOUT: %s.param: @CallGenericMethod.%T.loc17_22.2 (%T) = value_param runtime_param1 +// CHECK:STDOUT: %T.ref.loc17_57: type = name_ref T, %T.loc17_22.1 [symbolic = %T.loc17_22.2 (constants.%T)] +// CHECK:STDOUT: %s: @CallGenericMethod.%T.loc17_22.2 (%T) = bind_name s, %s.param // CHECK:STDOUT: } // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } @@ -316,36 +387,36 @@ fn G() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @CallGenericMethod2(%T.loc17_23.1: type, %U.loc17_33.1: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2)) { -// CHECK:STDOUT: %T.loc17_23.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc17_23.2 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc17_23.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_23.2 (constants.%T.patt)] -// CHECK:STDOUT: %Generic.type.loc17_46.2: type = facet_type <@Generic, @Generic(%T.loc17_23.2)> [symbolic = %Generic.type.loc17_46.2 (constants.%Generic.type.91ccba.2)] -// CHECK:STDOUT: %U.loc17_33.2: %Generic.type.91ccba.2 = bind_symbolic_name U, 1 [symbolic = %U.loc17_33.2 (constants.%U)] -// CHECK:STDOUT: %U.patt.loc17_33.2: %Generic.type.91ccba.2 = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_33.2 (constants.%U.patt)] -// CHECK:STDOUT: %U.as_type.loc17_52.2: type = facet_access_type %U.loc17_33.2 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] +// CHECK:STDOUT: generic fn @CallGenericMethod(%T.loc17_22.1: type, %U.loc17_32.1: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2)) { +// CHECK:STDOUT: %T.loc17_22.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc17_22.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc17_22.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_22.2 (constants.%T.patt)] +// CHECK:STDOUT: %Generic.type.loc17_45.2: type = facet_type <@Generic, @Generic(%T.loc17_22.2)> [symbolic = %Generic.type.loc17_45.2 (constants.%Generic.type.91ccba.2)] +// CHECK:STDOUT: %U.loc17_32.2: %Generic.type.91ccba.2 = bind_symbolic_name U, 1 [symbolic = %U.loc17_32.2 (constants.%U)] +// CHECK:STDOUT: %U.patt.loc17_32.2: %Generic.type.91ccba.2 = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc17_32.2 (constants.%U.patt)] +// CHECK:STDOUT: %U.as_type.loc17_51.2: type = facet_access_type %U.loc17_32.2 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc17_50: = require_complete_type @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type) [symbolic = %require_complete.loc17_50 (constants.%require_complete.7b2)] -// CHECK:STDOUT: %require_complete.loc17_56: = require_complete_type @CallGenericMethod2.%T.loc17_23.2 (%T) [symbolic = %require_complete.loc17_56 (constants.%require_complete.4ae)] -// CHECK:STDOUT: %require_complete.loc18: = require_complete_type @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) [symbolic = %require_complete.loc18 (constants.%require_complete.02a)] -// CHECK:STDOUT: %Generic.assoc_type: type = assoc_entity_type @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) [symbolic = %Generic.assoc_type (constants.%Generic.assoc_type.de973d.2)] -// CHECK:STDOUT: %assoc0: @CallGenericMethod2.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = assoc_entity element0, @Generic.%F.decl [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] -// CHECK:STDOUT: %U.as_wit.loc18_4.2: = facet_access_witness %U.loc17_33.2 [symbolic = %U.as_wit.loc18_4.2 (constants.%U.as_wit)] -// CHECK:STDOUT: %F.type: type = fn_type @F.1, @Generic(%T.loc17_23.2) [symbolic = %F.type (constants.%F.type.f439a9.2)] -// CHECK:STDOUT: %Generic.facet: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = facet_value %U.as_type.loc17_52.2, %U.as_wit.loc18_4.2 [symbolic = %Generic.facet (constants.%Generic.facet.2ea)] +// CHECK:STDOUT: %require_complete.loc17_49: = require_complete_type @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type) [symbolic = %require_complete.loc17_49 (constants.%require_complete.7b2)] +// CHECK:STDOUT: %require_complete.loc17_55: = require_complete_type @CallGenericMethod.%T.loc17_22.2 (%T) [symbolic = %require_complete.loc17_55 (constants.%require_complete.4ae)] +// CHECK:STDOUT: %require_complete.loc18: = require_complete_type @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) [symbolic = %require_complete.loc18 (constants.%require_complete.02a)] +// CHECK:STDOUT: %Generic.assoc_type: type = assoc_entity_type @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) [symbolic = %Generic.assoc_type (constants.%Generic.assoc_type.de973d.2)] +// CHECK:STDOUT: %assoc0: @CallGenericMethod.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = assoc_entity element0, @Generic.%F.decl [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] +// CHECK:STDOUT: %U.as_wit.loc18_4.2: = facet_access_witness %U.loc17_32.2 [symbolic = %U.as_wit.loc18_4.2 (constants.%U.as_wit)] +// CHECK:STDOUT: %F.type: type = fn_type @F.1, @Generic(%T.loc17_22.2) [symbolic = %F.type (constants.%F.type.f439a9.2)] +// CHECK:STDOUT: %Generic.facet: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = facet_value %U.as_type.loc17_51.2, %U.as_wit.loc18_4.2 [symbolic = %Generic.facet (constants.%Generic.facet.2ea)] // CHECK:STDOUT: %.loc18_4.3: type = fn_type_with_self_type %F.type, %Generic.facet [symbolic = %.loc18_4.3 (constants.%.da8)] -// CHECK:STDOUT: %impl.elem0.loc18_4.2: @CallGenericMethod2.%.loc18_4.3 (%.da8) = impl_witness_access %U.as_wit.loc18_4.2, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %specific_fn.loc18_4.2: = specific_function %impl.elem0.loc18_4.2, @F.1(%T.loc17_23.2, %Generic.facet) [symbolic = %specific_fn.loc18_4.2 (constants.%specific_fn)] +// CHECK:STDOUT: %impl.elem0.loc18_4.2: @CallGenericMethod.%.loc18_4.3 (%.da8) = impl_witness_access %U.as_wit.loc18_4.2, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_fn.loc18_4.2: = specific_function %impl.elem0.loc18_4.2, @F.1(%T.loc17_22.2, %Generic.facet) [symbolic = %specific_fn.loc18_4.2 (constants.%specific_fn)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type, %U.param_patt: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2)](%a.param_patt: @CallGenericMethod2.%U.as_type.loc17_52.2 (%U.as_type), %s.param_patt: @CallGenericMethod2.%T.loc17_23.2 (%T)) { +// CHECK:STDOUT: fn[%T.param_patt: type, %U.param_patt: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2)](%a.param_patt: @CallGenericMethod.%U.as_type.loc17_51.2 (%U.as_type), %s.param_patt: @CallGenericMethod.%T.loc17_22.2 (%T)) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %U.ref.loc18: @CallGenericMethod2.%Generic.type.loc17_46.2 (%Generic.type.91ccba.2) = name_ref U, %U.loc17_33.1 [symbolic = %U.loc17_33.2 (constants.%U)] -// CHECK:STDOUT: %.loc18_4.1: @CallGenericMethod2.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = specific_constant @Generic.%assoc0.loc7_9.1, @Generic(constants.%T) [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] -// CHECK:STDOUT: %F.ref: @CallGenericMethod2.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = name_ref F, %.loc18_4.1 [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] -// CHECK:STDOUT: %U.as_type.loc18: type = facet_access_type %U.ref.loc18 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] -// CHECK:STDOUT: %.loc18_4.2: type = converted %U.ref.loc18, %U.as_type.loc18 [symbolic = %U.as_type.loc17_52.2 (constants.%U.as_type)] +// CHECK:STDOUT: %U.ref.loc18: @CallGenericMethod.%Generic.type.loc17_45.2 (%Generic.type.91ccba.2) = name_ref U, %U.loc17_32.1 [symbolic = %U.loc17_32.2 (constants.%U)] +// CHECK:STDOUT: %.loc18_4.1: @CallGenericMethod.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = specific_constant @Generic.%assoc0.loc7_9.1, @Generic(constants.%T) [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] +// CHECK:STDOUT: %F.ref: @CallGenericMethod.%Generic.assoc_type (%Generic.assoc_type.de973d.2) = name_ref F, %.loc18_4.1 [symbolic = %assoc0 (constants.%assoc0.29ce53.2)] +// CHECK:STDOUT: %U.as_type.loc18: type = facet_access_type %U.ref.loc18 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] +// CHECK:STDOUT: %.loc18_4.2: type = converted %U.ref.loc18, %U.as_type.loc18 [symbolic = %U.as_type.loc17_51.2 (constants.%U.as_type)] // CHECK:STDOUT: %U.as_wit.loc18_4.1: = facet_access_witness %U.ref.loc18 [symbolic = %U.as_wit.loc18_4.2 (constants.%U.as_wit)] -// CHECK:STDOUT: %impl.elem0.loc18_4.1: @CallGenericMethod2.%.loc18_4.3 (%.da8) = impl_witness_access %U.as_wit.loc18_4.1, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @CallGenericMethod.%.loc18_4.3 (%.da8) = impl_witness_access %U.as_wit.loc18_4.1, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] // CHECK:STDOUT: %specific_fn.loc18_4.1: = specific_function %impl.elem0.loc18_4.1, @F.1(constants.%T, constants.%Generic.facet.2ea) [symbolic = %specific_fn.loc18_4.2 (constants.%specific_fn)] // CHECK:STDOUT: %F.call: init %empty_tuple.type = call %specific_fn.loc18_4.1() // CHECK:STDOUT: return @@ -354,25 +425,25 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %CallGenericMethod2.ref: %CallGenericMethod2.type = name_ref CallGenericMethod2, file.%CallGenericMethod2.decl [concrete = constants.%CallGenericMethod2] -// CHECK:STDOUT: %.loc22_23.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %CallGenericMethod.ref: %CallGenericMethod.type = name_ref CallGenericMethod, file.%CallGenericMethod.decl [concrete = constants.%CallGenericMethod] +// CHECK:STDOUT: %.loc22_22.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric] -// CHECK:STDOUT: %.loc22_23.2: ref %ImplsGeneric = temporary_storage -// CHECK:STDOUT: %.loc22_23.3: init %ImplsGeneric = class_init (), %.loc22_23.2 [concrete = constants.%ImplsGeneric.val] -// CHECK:STDOUT: %.loc22_23.4: ref %ImplsGeneric = temporary %.loc22_23.2, %.loc22_23.3 -// CHECK:STDOUT: %.loc22_25.1: ref %ImplsGeneric = converted %.loc22_23.1, %.loc22_23.4 -// CHECK:STDOUT: %.loc22_43.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc22_22.2: ref %ImplsGeneric = temporary_storage +// CHECK:STDOUT: %.loc22_22.3: init %ImplsGeneric = class_init (), %.loc22_22.2 [concrete = constants.%ImplsGeneric.val] +// CHECK:STDOUT: %.loc22_22.4: ref %ImplsGeneric = temporary %.loc22_22.2, %.loc22_22.3 +// CHECK:STDOUT: %.loc22_24.1: ref %ImplsGeneric = converted %.loc22_22.1, %.loc22_22.4 +// CHECK:STDOUT: %.loc22_42.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %GenericParam.ref: type = name_ref GenericParam, file.%GenericParam.decl [concrete = constants.%GenericParam] -// CHECK:STDOUT: %.loc22_43.2: ref %GenericParam = temporary_storage -// CHECK:STDOUT: %.loc22_43.3: init %GenericParam = class_init (), %.loc22_43.2 [concrete = constants.%GenericParam.val] -// CHECK:STDOUT: %.loc22_43.4: ref %GenericParam = temporary %.loc22_43.2, %.loc22_43.3 -// CHECK:STDOUT: %.loc22_45.1: ref %GenericParam = converted %.loc22_43.1, %.loc22_43.4 +// CHECK:STDOUT: %.loc22_42.2: ref %GenericParam = temporary_storage +// CHECK:STDOUT: %.loc22_42.3: init %GenericParam = class_init (), %.loc22_42.2 [concrete = constants.%GenericParam.val] +// CHECK:STDOUT: %.loc22_42.4: ref %GenericParam = temporary %.loc22_42.2, %.loc22_42.3 +// CHECK:STDOUT: %.loc22_44.1: ref %GenericParam = converted %.loc22_42.1, %.loc22_42.4 // CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, constants.%impl_witness [concrete = constants.%Generic.facet.b0a] -// CHECK:STDOUT: %.loc22_60: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.b0a] -// CHECK:STDOUT: %CallGenericMethod2.specific_fn: = specific_function %CallGenericMethod2.ref, @CallGenericMethod2(constants.%GenericParam, %.loc22_60) [concrete = constants.%CallGenericMethod2.specific_fn] -// CHECK:STDOUT: %.loc22_25.2: %ImplsGeneric = bind_value %.loc22_25.1 -// CHECK:STDOUT: %.loc22_45.2: %GenericParam = bind_value %.loc22_45.1 -// CHECK:STDOUT: %CallGenericMethod2.call: init %empty_tuple.type = call %CallGenericMethod2.specific_fn(%.loc22_25.2, %.loc22_45.2) +// CHECK:STDOUT: %.loc22_59: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.b0a] +// CHECK:STDOUT: %CallGenericMethod.specific_fn: = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, %.loc22_59) [concrete = constants.%CallGenericMethod.specific_fn] +// CHECK:STDOUT: %.loc22_24.2: %ImplsGeneric = bind_value %.loc22_24.1 +// CHECK:STDOUT: %.loc22_44.2: %GenericParam = bind_value %.loc22_44.1 +// CHECK:STDOUT: %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn(%.loc22_24.2, %.loc22_44.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -413,32 +484,32 @@ fn G() { // CHECK:STDOUT: %assoc0.loc7_9.2 => constants.%assoc0.29ce53.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @CallGenericMethod2(constants.%T, constants.%U) { -// CHECK:STDOUT: %T.loc17_23.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc17_23.2 => constants.%T -// CHECK:STDOUT: %Generic.type.loc17_46.2 => constants.%Generic.type.91ccba.2 -// CHECK:STDOUT: %U.loc17_33.2 => constants.%U -// CHECK:STDOUT: %U.patt.loc17_33.2 => constants.%U -// CHECK:STDOUT: %U.as_type.loc17_52.2 => constants.%U.as_type +// CHECK:STDOUT: specific @CallGenericMethod(constants.%T, constants.%U) { +// CHECK:STDOUT: %T.loc17_22.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc17_22.2 => constants.%T +// CHECK:STDOUT: %Generic.type.loc17_45.2 => constants.%Generic.type.91ccba.2 +// CHECK:STDOUT: %U.loc17_32.2 => constants.%U +// CHECK:STDOUT: %U.patt.loc17_32.2 => constants.%U +// CHECK:STDOUT: %U.as_type.loc17_51.2 => constants.%U.as_type // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Generic(@CallGenericMethod2.%T.loc17_23.2) {} +// CHECK:STDOUT: specific @Generic(@CallGenericMethod.%T.loc17_22.2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @F.1(constants.%T, constants.%Generic.facet.2ea) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @F.1(@CallGenericMethod2.%T.loc17_23.2, @CallGenericMethod2.%Generic.facet) {} +// CHECK:STDOUT: specific @F.1(@CallGenericMethod.%T.loc17_22.2, @CallGenericMethod.%Generic.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @CallGenericMethod2(constants.%GenericParam, @G.%.loc22_60) { -// CHECK:STDOUT: %T.loc17_23.2 => constants.%GenericParam -// CHECK:STDOUT: %T.patt.loc17_23.2 => constants.%GenericParam -// CHECK:STDOUT: %Generic.type.loc17_46.2 => constants.%Generic.type.769 -// CHECK:STDOUT: %U.loc17_33.2 => constants.%Generic.facet.b0a -// CHECK:STDOUT: %U.patt.loc17_33.2 => constants.%Generic.facet.b0a -// CHECK:STDOUT: %U.as_type.loc17_52.2 => constants.%ImplsGeneric +// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, @G.%.loc22_59) { +// CHECK:STDOUT: %T.loc17_22.2 => constants.%GenericParam +// CHECK:STDOUT: %T.patt.loc17_22.2 => constants.%GenericParam +// CHECK:STDOUT: %Generic.type.loc17_45.2 => constants.%Generic.type.769 +// CHECK:STDOUT: %U.loc17_32.2 => constants.%Generic.facet.b0a +// CHECK:STDOUT: %U.patt.loc17_32.2 => constants.%Generic.facet.b0a +// CHECK:STDOUT: %U.as_type.loc17_51.2 => constants.%ImplsGeneric // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc17_50 => constants.%complete_type.357 -// CHECK:STDOUT: %require_complete.loc17_56 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc17_49 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc17_55 => constants.%complete_type.357 // CHECK:STDOUT: %require_complete.loc18 => constants.%complete_type.997 // CHECK:STDOUT: %Generic.assoc_type => constants.%Generic.assoc_type.9f1 // CHECK:STDOUT: %assoc0 => constants.%assoc0.9b7 @@ -450,12 +521,876 @@ fn G() { // CHECK:STDOUT: %specific_fn.loc18_4.2 => constants.%F.specific_fn // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @CallGenericMethod2(constants.%GenericParam, constants.%Generic.facet.b0a) { -// CHECK:STDOUT: %T.loc17_23.2 => constants.%GenericParam -// CHECK:STDOUT: %T.patt.loc17_23.2 => constants.%GenericParam -// CHECK:STDOUT: %Generic.type.loc17_46.2 => constants.%Generic.type.769 -// CHECK:STDOUT: %U.loc17_33.2 => constants.%Generic.facet.b0a -// CHECK:STDOUT: %U.patt.loc17_33.2 => constants.%Generic.facet.b0a -// CHECK:STDOUT: %U.as_type.loc17_52.2 => constants.%ImplsGeneric +// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.b0a) { +// CHECK:STDOUT: %T.loc17_22.2 => constants.%GenericParam +// CHECK:STDOUT: %T.patt.loc17_22.2 => constants.%GenericParam +// CHECK:STDOUT: %Generic.type.loc17_45.2 => constants.%Generic.type.769 +// CHECK:STDOUT: %U.loc17_32.2 => constants.%Generic.facet.b0a +// CHECK:STDOUT: %U.patt.loc17_32.2 => constants.%Generic.facet.b0a +// CHECK:STDOUT: %U.as_type.loc17_51.2 => constants.%ImplsGeneric +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- multiple_generic_params_one_fixed_one_deduced.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %V: type = bind_symbolic_name V, 0 [symbolic] +// CHECK:STDOUT: %V.patt: type = symbolic_binding_pattern V, 0 [symbolic] +// CHECK:STDOUT: %W: type = bind_symbolic_name W, 1 [symbolic] +// CHECK:STDOUT: %W.patt: type = symbolic_binding_pattern W, 1 [symbolic] +// CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] +// CHECK:STDOUT: %I.type.f76: type = facet_type <@I, @I(%V, %W)> [symbolic] +// CHECK:STDOUT: %Self: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.e01: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %I.type.bea: type = facet_type <@I, @I(%T.8b3, %empty_tuple.type)> [symbolic] +// CHECK:STDOUT: %require_complete.5ce: = require_complete_type %I.type.bea [symbolic] +// CHECK:STDOUT: %impl_witness.298: = impl_witness (), @impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %I.type.202: type = facet_type <@I, @I(%empty_struct_type, %empty_tuple.type)> [concrete] +// CHECK:STDOUT: %T.e96: %I.type.202 = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.5b9: %I.type.202 = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.e96 [symbolic] +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.c8b: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %B.type: type = fn_type @B [concrete] +// CHECK:STDOUT: %B: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %complete_type.3d9: = complete_type_witness %I.type.202 [concrete] +// CHECK:STDOUT: %impl_witness.e3d: = impl_witness (), @impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %I.facet: %I.type.202 = facet_value %C, %impl_witness.e3d [concrete] +// CHECK:STDOUT: %A.specific_fn: = specific_function %A, @A(%I.facet) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %I.decl: %I.type.dac = interface_decl @I [concrete = constants.%I.generic] { +// CHECK:STDOUT: %V.patt.loc5_13.1: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %V.param_patt: type = value_param_pattern %V.patt.loc5_13.1, runtime_param [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.patt.loc5_23.1: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: %W.param_patt: type = value_param_pattern %W.patt.loc5_23.1, runtime_param [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %V.param: type = value_param runtime_param +// CHECK:STDOUT: %V.loc5_13.1: type = bind_symbolic_name V, 0, %V.param [symbolic = %V.loc5_13.2 (constants.%V)] +// CHECK:STDOUT: %W.param: type = value_param runtime_param +// CHECK:STDOUT: %W.loc5_23.1: type = bind_symbolic_name W, 1, %W.param [symbolic = %W.loc5_23.2 (constants.%W)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @impl [concrete] { +// CHECK:STDOUT: %T.patt.loc9_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc9_14.1, runtime_param [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc9_14.1 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %.loc9_35: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc9_36: type = converted %.loc9_35, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %I.type.loc9_36.1: type = facet_type <@I, @I(constants.%T.8b3, constants.%empty_tuple.type)> [symbolic = %I.type.loc9_36.2 (constants.%I.type.bea)] +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc9_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(constants.%T.8b3) [symbolic = @impl.%impl_witness (constants.%impl_witness.298)] +// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { +// CHECK:STDOUT: %T.patt.loc11_6.1: %I.type.202 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.5b9)] +// CHECK:STDOUT: %T.param_patt: %I.type.202 = value_param_pattern %T.patt.loc11_6.1, runtime_param [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.5b9)] +// CHECK:STDOUT: %t.patt: @A.%T.as_type.loc11_24.2 (%T.as_type) = binding_pattern t +// CHECK:STDOUT: %t.param_patt: @A.%T.as_type.loc11_24.2 (%T.as_type) = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %I.type.202 = value_param runtime_param +// CHECK:STDOUT: %.loc11_18.1: type = splice_block %I.type [concrete = constants.%I.type.202] { +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %.loc11_13: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_17: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc11_18.2: type = converted %.loc11_13, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc11_18.3: type = converted %.loc11_17, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(constants.%empty_struct_type, constants.%empty_tuple.type)> [concrete = constants.%I.type.202] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc11_6.1: %I.type.202 = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc11_6.2 (constants.%T.e96)] +// CHECK:STDOUT: %t.param: @A.%T.as_type.loc11_24.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc11_24.1: type = splice_block %.loc11_24.2 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %I.type.202 = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T.e96)] +// CHECK:STDOUT: %T.as_type.loc11_24.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc11_24.2: type = converted %T.ref, %T.as_type.loc11_24.1 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @A.%T.as_type.loc11_24.2 (%T.as_type) = bind_name t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(%V.loc5_13.1: type, %W.loc5_23.1: type) { +// CHECK:STDOUT: %V.loc5_13.2: type = bind_symbolic_name V, 0 [symbolic = %V.loc5_13.2 (constants.%V)] +// CHECK:STDOUT: %V.patt.loc5_13.2: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.loc5_23.2: type = bind_symbolic_name W, 1 [symbolic = %W.loc5_23.2 (constants.%W)] +// CHECK:STDOUT: %W.patt.loc5_23.2: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%V.loc5_13.2, %W.loc5_23.2)> [symbolic = %I.type (constants.%I.type.f76)] +// CHECK:STDOUT: %Self.2: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic = %Self.2 (constants.%Self)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I.%I.type (%I.type.f76) = bind_symbolic_name Self, 2 [symbolic = %Self.2 (constants.%Self)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @impl(%T.loc9_14.1: type) { +// CHECK:STDOUT: %T.loc9_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt.loc9_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %I.type.loc9_36.2: type = facet_type <@I, @I(%T.loc9_14.2, constants.%empty_tuple.type)> [symbolic = %I.type.loc9_36.2 (constants.%I.type.bea)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.%I.type.loc9_36.2 (%I.type.bea) [symbolic = %require_complete (constants.%require_complete.5ce)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(%T.loc9_14.2) [symbolic = %impl_witness (constants.%impl_witness.298)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: impl: %C.ref as %I.type.loc9_36.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A(%T.loc11_6.1: %I.type.202) { +// CHECK:STDOUT: %T.loc11_6.2: %I.type.202 = bind_symbolic_name T, 0 [symbolic = %T.loc11_6.2 (constants.%T.e96)] +// CHECK:STDOUT: %T.patt.loc11_6.2: %I.type.202 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.5b9)] +// CHECK:STDOUT: %T.as_type.loc11_24.2: type = facet_access_type %T.loc11_6.2 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.%T.as_type.loc11_24.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete.c8b)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %I.type.202](%t.param_patt: @A.%T.as_type.loc11_24.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %.loc14_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc14_6.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc14_6.3: init %C = class_init (), %.loc14_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc14_6.4: ref %C = temporary %.loc14_6.2, %.loc14_6.3 +// CHECK:STDOUT: %.loc14_8.1: ref %C = converted %.loc14_6.1, %.loc14_6.4 +// CHECK:STDOUT: %I.facet.loc14_12.1: %I.type.202 = facet_value constants.%C, constants.%impl_witness.e3d [concrete = constants.%I.facet] +// CHECK:STDOUT: %.loc14_12.1: %I.type.202 = converted constants.%C, %I.facet.loc14_12.1 [concrete = constants.%I.facet] +// CHECK:STDOUT: %I.facet.loc14_12.2: %I.type.202 = facet_value constants.%C, constants.%impl_witness.e3d [concrete = constants.%I.facet] +// CHECK:STDOUT: %.loc14_12.2: %I.type.202 = converted constants.%C, %I.facet.loc14_12.2 [concrete = constants.%I.facet] +// CHECK:STDOUT: %A.specific_fn: = specific_function %A.ref, @A(constants.%I.facet) [concrete = constants.%A.specific_fn] +// CHECK:STDOUT: %.loc14_8.2: %C = bind_value %.loc14_8.1 +// CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.specific_fn(%.loc14_8.2) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%V, constants.%W) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%V +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%V +// CHECK:STDOUT: %W.loc5_23.2 => constants.%W +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%W +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(%V.loc5_13.2, %W.loc5_23.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T.8b3, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%T.8b3 +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%T.8b3 +// CHECK:STDOUT: %W.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.bea +// CHECK:STDOUT: %Self.2 => constants.%Self +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%T.8b3) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %I.type.loc9_36.2 => constants.%I.type.bea +// CHECK:STDOUT: %require_complete => constants.%require_complete.5ce +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.298 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(@impl.%T.loc9_14.2, constants.%empty_tuple.type) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(%T.loc9_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%empty_struct_type, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.202 +// CHECK:STDOUT: %Self.2 => constants.%Self +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A(constants.%T.e96) { +// CHECK:STDOUT: %T.loc11_6.2 => constants.%T.e96 +// CHECK:STDOUT: %T.patt.loc11_6.2 => constants.%T.e96 +// CHECK:STDOUT: %T.as_type.loc11_24.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%empty_struct_type) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %I.type.loc9_36.2 => constants.%I.type.202 +// CHECK:STDOUT: %require_complete => constants.%complete_type.3d9 +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.e3d +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A(constants.%I.facet) { +// CHECK:STDOUT: %T.loc11_6.2 => constants.%I.facet +// CHECK:STDOUT: %T.patt.loc11_6.2 => constants.%I.facet +// CHECK:STDOUT: %T.as_type.loc11_24.2 => constants.%C +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_mismatch_impl_constraint_with_fixed_specific.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %V: type = bind_symbolic_name V, 0 [symbolic] +// CHECK:STDOUT: %V.patt: type = symbolic_binding_pattern V, 0 [symbolic] +// CHECK:STDOUT: %W: type = bind_symbolic_name W, 1 [symbolic] +// CHECK:STDOUT: %W.patt: type = symbolic_binding_pattern W, 1 [symbolic] +// CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] +// CHECK:STDOUT: %I.type.f76: type = facet_type <@I, @I(%V, %W)> [symbolic] +// CHECK:STDOUT: %Self.770: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.e01: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %I.type.bea: type = facet_type <@I, @I(%T.8b3, %empty_tuple.type)> [symbolic] +// CHECK:STDOUT: %require_complete.5ce: = require_complete_type %I.type.bea [symbolic] +// CHECK:STDOUT: %impl_witness.298: = impl_witness (), @impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %I.type.906: type = facet_type <@I, @I(%empty_struct_type, %empty_struct_type)> [concrete] +// CHECK:STDOUT: %T.4b2: %I.type.906 = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.6fc: %I.type.906 = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.4b2 [symbolic] +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.d5b: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %B.type: type = fn_type @B [concrete] +// CHECK:STDOUT: %B: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %I.type.202: type = facet_type <@I, @I(%empty_struct_type, %empty_tuple.type)> [concrete] +// CHECK:STDOUT: %complete_type.3d9: = complete_type_witness %I.type.202 [concrete] +// CHECK:STDOUT: %impl_witness.e3d: = impl_witness (), @impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d62: type = facet_type <@ImplicitAs, @ImplicitAs(%T.8b3)> [symbolic] +// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%T.8b3) [symbolic] +// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic] +// CHECK:STDOUT: %ImplicitAs.assoc_type.837: type = assoc_entity_type %ImplicitAs.type.d62 [symbolic] +// CHECK:STDOUT: %assoc0.43db8b.1: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.442: type = facet_type <@ImplicitAs, @ImplicitAs(%I.type.906)> [concrete] +// CHECK:STDOUT: %Convert.type.b43: type = fn_type @Convert, @ImplicitAs(%I.type.906) [concrete] +// CHECK:STDOUT: %Convert.2fc: %Convert.type.b43 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.assoc_type.128: type = assoc_entity_type %ImplicitAs.type.442 [concrete] +// CHECK:STDOUT: %assoc0.5ba: %ImplicitAs.assoc_type.128 = assoc_entity element0, imports.%Core.import_ref.207961.1 [concrete] +// CHECK:STDOUT: %assoc0.43db8b.2: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.2 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.f6b058.1: type = import_ref Core//default, loc4_22, loaded [symbolic = @ImplicitAs.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.ff5 = import_ref Core//default, inst26 [no loc], unloaded +// CHECK:STDOUT: %Core.import_ref.630: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = import_ref Core//default, loc5_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.43db8b.2)] +// CHECK:STDOUT: %Core.Convert = import_ref Core//default, Convert, unloaded +// CHECK:STDOUT: %Core.import_ref.f6b058.2: type = import_ref Core//default, loc4_22, loaded [symbolic = @ImplicitAs.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.ce1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) = import_ref Core//default, inst26 [no loc], loaded [symbolic = @ImplicitAs.%Self (constants.%Self.519)] +// CHECK:STDOUT: %Core.import_ref.207961.1 = import_ref Core//default, loc5_32, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %I.decl: %I.type.dac = interface_decl @I [concrete = constants.%I.generic] { +// CHECK:STDOUT: %V.patt.loc5_13.1: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %V.param_patt: type = value_param_pattern %V.patt.loc5_13.1, runtime_param [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.patt.loc5_23.1: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: %W.param_patt: type = value_param_pattern %W.patt.loc5_23.1, runtime_param [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %V.param: type = value_param runtime_param +// CHECK:STDOUT: %V.loc5_13.1: type = bind_symbolic_name V, 0, %V.param [symbolic = %V.loc5_13.2 (constants.%V)] +// CHECK:STDOUT: %W.param: type = value_param runtime_param +// CHECK:STDOUT: %W.loc5_23.1: type = bind_symbolic_name W, 1, %W.param [symbolic = %W.loc5_23.2 (constants.%W)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @impl [concrete] { +// CHECK:STDOUT: %T.patt.loc9_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc9_14.1, runtime_param [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc9_14.1 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %.loc9_35: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc9_36: type = converted %.loc9_35, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %I.type.loc9_36.1: type = facet_type <@I, @I(constants.%T.8b3, constants.%empty_tuple.type)> [symbolic = %I.type.loc9_36.2 (constants.%I.type.bea)] +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc9_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(constants.%T.8b3) [symbolic = @impl.%impl_witness (constants.%impl_witness.298)] +// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { +// CHECK:STDOUT: %T.patt.loc11_6.1: %I.type.906 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.6fc)] +// CHECK:STDOUT: %T.param_patt: %I.type.906 = value_param_pattern %T.patt.loc11_6.1, runtime_param [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.6fc)] +// CHECK:STDOUT: %t.patt: @A.%T.as_type.loc11_24.2 (%T.as_type) = binding_pattern t +// CHECK:STDOUT: %t.param_patt: @A.%T.as_type.loc11_24.2 (%T.as_type) = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %I.type.906 = value_param runtime_param +// CHECK:STDOUT: %.loc11_18.1: type = splice_block %I.type [concrete = constants.%I.type.906] { +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %.loc11_13: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_17: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc11_18.2: type = converted %.loc11_13, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc11_18.3: type = converted %.loc11_17, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(constants.%empty_struct_type, constants.%empty_struct_type)> [concrete = constants.%I.type.906] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc11_6.1: %I.type.906 = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc11_6.2 (constants.%T.4b2)] +// CHECK:STDOUT: %t.param: @A.%T.as_type.loc11_24.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc11_24.1: type = splice_block %.loc11_24.2 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %I.type.906 = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T.4b2)] +// CHECK:STDOUT: %T.as_type.loc11_24.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc11_24.2: type = converted %T.ref, %T.as_type.loc11_24.1 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @A.%T.as_type.loc11_24.2 (%T.as_type) = bind_name t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(%V.loc5_13.1: type, %W.loc5_23.1: type) { +// CHECK:STDOUT: %V.loc5_13.2: type = bind_symbolic_name V, 0 [symbolic = %V.loc5_13.2 (constants.%V)] +// CHECK:STDOUT: %V.patt.loc5_13.2: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc5_13.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.loc5_23.2: type = bind_symbolic_name W, 1 [symbolic = %W.loc5_23.2 (constants.%W)] +// CHECK:STDOUT: %W.patt.loc5_23.2: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc5_23.2 (constants.%W.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%V.loc5_13.2, %W.loc5_23.2)> [symbolic = %I.type (constants.%I.type.f76)] +// CHECK:STDOUT: %Self.2: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic = %Self.2 (constants.%Self.770)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @I.%I.type (%I.type.f76) = bind_symbolic_name Self, 2 [symbolic = %Self.2 (constants.%Self.770)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @ImplicitAs(imports.%Core.import_ref.f6b058.1: type) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.d62)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.519)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%T) [symbolic = %Convert.type (constants.%Convert.type.275)] +// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = struct_value () [symbolic = %Convert (constants.%Convert.42e)] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.837)] +// CHECK:STDOUT: %assoc0: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.43db8b.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Core.import_ref.ff5 +// CHECK:STDOUT: .Convert = imports.%Core.import_ref.630 +// CHECK:STDOUT: witness = (imports.%Core.Convert) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @impl(%T.loc9_14.1: type) { +// CHECK:STDOUT: %T.loc9_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt.loc9_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %I.type.loc9_36.2: type = facet_type <@I, @I(%T.loc9_14.2, constants.%empty_tuple.type)> [symbolic = %I.type.loc9_36.2 (constants.%I.type.bea)] +// CHECK:STDOUT: %require_complete: = require_complete_type @impl.%I.type.loc9_36.2 (%I.type.bea) [symbolic = %require_complete (constants.%require_complete.5ce)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(%T.loc9_14.2) [symbolic = %impl_witness (constants.%impl_witness.298)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: impl: %C.ref as %I.type.loc9_36.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A(%T.loc11_6.1: %I.type.906) { +// CHECK:STDOUT: %T.loc11_6.2: %I.type.906 = bind_symbolic_name T, 0 [symbolic = %T.loc11_6.2 (constants.%T.4b2)] +// CHECK:STDOUT: %T.patt.loc11_6.2: %I.type.906 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.6fc)] +// CHECK:STDOUT: %T.as_type.loc11_24.2: type = facet_access_type %T.loc11_6.2 [symbolic = %T.as_type.loc11_24.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.%T.as_type.loc11_24.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete.d5b)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %I.type.906](%t.param_patt: @A.%T.as_type.loc11_24.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %.loc24_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc24_6.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc24_6.3: init %C = class_init (), %.loc24_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc24_6.4: ref %C = temporary %.loc24_6.2, %.loc24_6.3 +// CHECK:STDOUT: %.loc24_8: ref %C = converted %.loc24_6.1, %.loc24_6.4 +// CHECK:STDOUT: %.loc24_12: %I.type.906 = converted constants.%C, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert(imports.%Core.import_ref.f6b058.2: type, imports.%Core.import_ref.ce1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62)) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.d62)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.519)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.%Self.as_type (%Self.as_type)]() -> @Convert.%T (%T.8b3); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%V, constants.%W) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%V +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%V +// CHECK:STDOUT: %W.loc5_23.2 => constants.%W +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%W +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(%V.loc5_13.2, %W.loc5_23.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T.8b3, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%T.8b3 +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%T.8b3 +// CHECK:STDOUT: %W.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.bea +// CHECK:STDOUT: %Self.2 => constants.%Self.770 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%T.8b3) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %I.type.loc9_36.2 => constants.%I.type.bea +// CHECK:STDOUT: %require_complete => constants.%require_complete.5ce +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.298 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(@impl.%T.loc9_14.2, constants.%empty_tuple.type) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(%T.loc9_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%empty_struct_type, constants.%empty_struct_type) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.loc5_23.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.906 +// CHECK:STDOUT: %Self.2 => constants.%Self.770 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A(constants.%T.4b2) { +// CHECK:STDOUT: %T.loc11_6.2 => constants.%T.4b2 +// CHECK:STDOUT: %T.patt.loc11_6.2 => constants.%T.4b2 +// CHECK:STDOUT: %T.as_type.loc11_24.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%empty_struct_type) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %I.type.loc9_36.2 => constants.%I.type.202 +// CHECK:STDOUT: %require_complete => constants.%complete_type.3d9 +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.e3d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%empty_struct_type, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %V.patt.loc5_13.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc5_23.2 => constants.%empty_tuple.type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.202 +// CHECK:STDOUT: %Self.2 => constants.%Self.770 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %T.patt => constants.%T.8b3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(@Convert.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert(constants.%T.8b3, constants.%Self.519) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.d62 +// CHECK:STDOUT: %Self => constants.%Self.519 +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%I.type.906) { +// CHECK:STDOUT: %T => constants.%I.type.906 +// CHECK:STDOUT: %T.patt => constants.%I.type.906 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.442 +// CHECK:STDOUT: %Self => constants.%Self.519 +// CHECK:STDOUT: %Convert.type => constants.%Convert.type.b43 +// CHECK:STDOUT: %Convert => constants.%Convert.2fc +// CHECK:STDOUT: %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.128 +// CHECK:STDOUT: %assoc0 => constants.%assoc0.5ba +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_mismatch_impl_self_with_fixed_specific.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %V: type = bind_symbolic_name V, 0 [symbolic] +// CHECK:STDOUT: %V.patt: type = symbolic_binding_pattern V, 0 [symbolic] +// CHECK:STDOUT: %W: type = bind_symbolic_name W, 1 [symbolic] +// CHECK:STDOUT: %W.patt: type = symbolic_binding_pattern W, 1 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %C.c6b: type = class_type @C, @C(%V, %W) [symbolic] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.e01: type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %C.463: type = class_type @C, @C(%T.8b3, %empty_tuple.type) [symbolic] +// CHECK:STDOUT: %impl_witness.1a1: = impl_witness (), @impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %T.826: %I.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt.3ad: %I.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.826 [symbolic] +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %B.type: type = fn_type @B [concrete] +// CHECK:STDOUT: %B: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %C.c74: type = class_type @C, @C(%empty_struct_type, %empty_struct_type) [concrete] +// CHECK:STDOUT: %C.val: %C.c74 = struct_value () [concrete] +// CHECK:STDOUT: %C.83b: type = class_type @C, @C(%empty_struct_type, %empty_tuple.type) [concrete] +// CHECK:STDOUT: %impl_witness.366: = impl_witness (), @impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d62: type = facet_type <@ImplicitAs, @ImplicitAs(%T.8b3)> [symbolic] +// CHECK:STDOUT: %Self.519: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%T.8b3) [symbolic] +// CHECK:STDOUT: %Convert.42e: %Convert.type.275 = struct_value () [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.519 [symbolic] +// CHECK:STDOUT: %ImplicitAs.assoc_type.837: type = assoc_entity_type %ImplicitAs.type.d62 [symbolic] +// CHECK:STDOUT: %assoc0.43db8b.1: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.c42: type = facet_type <@ImplicitAs, @ImplicitAs(%I.type)> [concrete] +// CHECK:STDOUT: %Convert.type.7ef: type = fn_type @Convert, @ImplicitAs(%I.type) [concrete] +// CHECK:STDOUT: %Convert.c77: %Convert.type.7ef = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.assoc_type.167: type = assoc_entity_type %ImplicitAs.type.c42 [concrete] +// CHECK:STDOUT: %assoc0.ae9: %ImplicitAs.assoc_type.167 = assoc_entity element0, imports.%Core.import_ref.207961.1 [concrete] +// CHECK:STDOUT: %assoc0.43db8b.2: %ImplicitAs.assoc_type.837 = assoc_entity element0, imports.%Core.import_ref.207961.2 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.f6b058.1: type = import_ref Core//default, loc4_22, loaded [symbolic = @ImplicitAs.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.ff5 = import_ref Core//default, inst26 [no loc], unloaded +// CHECK:STDOUT: %Core.import_ref.630: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = import_ref Core//default, loc5_32, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.43db8b.2)] +// CHECK:STDOUT: %Core.Convert = import_ref Core//default, Convert, unloaded +// CHECK:STDOUT: %Core.import_ref.f6b058.2: type = import_ref Core//default, loc4_22, loaded [symbolic = @ImplicitAs.%T (constants.%T.8b3)] +// CHECK:STDOUT: %Core.import_ref.ce1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) = import_ref Core//default, inst26 [no loc], loaded [symbolic = @ImplicitAs.%Self (constants.%Self.519)] +// CHECK:STDOUT: %Core.import_ref.207961.1 = import_ref Core//default, loc5_32, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { +// CHECK:STDOUT: %V.patt.loc7_9.1: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc7_9.2 (constants.%V.patt)] +// CHECK:STDOUT: %V.param_patt: type = value_param_pattern %V.patt.loc7_9.1, runtime_param [symbolic = %V.patt.loc7_9.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.patt.loc7_19.1: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc7_19.2 (constants.%W.patt)] +// CHECK:STDOUT: %W.param_patt: type = value_param_pattern %W.patt.loc7_19.1, runtime_param [symbolic = %W.patt.loc7_19.2 (constants.%W.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %V.param: type = value_param runtime_param +// CHECK:STDOUT: %V.loc7_9.1: type = bind_symbolic_name V, 0, %V.param [symbolic = %V.loc7_9.2 (constants.%V)] +// CHECK:STDOUT: %W.param: type = value_param runtime_param +// CHECK:STDOUT: %W.loc7_19.1: type = bind_symbolic_name W, 1, %W.param [symbolic = %W.loc7_19.2 (constants.%W)] +// CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @impl [concrete] { +// CHECK:STDOUT: %T.patt.loc9_14.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc9_14.1, runtime_param [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc9_14.1 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %.loc9_30: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc9_31: type = converted %.loc9_30, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %C.loc9_31.1: type = class_type @C, @C(constants.%T.8b3, constants.%empty_tuple.type) [symbolic = %C.loc9_31.2 (constants.%C.463)] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %T.param: type = value_param runtime_param +// CHECK:STDOUT: %T.loc9_14.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(constants.%T.8b3) [symbolic = @impl.%impl_witness (constants.%impl_witness.1a1)] +// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { +// CHECK:STDOUT: %T.patt.loc11_6.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.3ad)] +// CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc11_6.1, runtime_param [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.3ad)] +// CHECK:STDOUT: %t.patt: @A.%T.as_type.loc11_16.2 (%T.as_type) = binding_pattern t +// CHECK:STDOUT: %t.param_patt: @A.%T.as_type.loc11_16.2 (%T.as_type) = value_param_pattern %t.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %T.loc11_6.1: %I.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc11_6.2 (constants.%T.826)] +// CHECK:STDOUT: %t.param: @A.%T.as_type.loc11_16.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc11_16.1: type = splice_block %.loc11_16.2 [symbolic = %T.as_type.loc11_16.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %I.type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T.826)] +// CHECK:STDOUT: %T.as_type.loc11_16.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc11_16.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc11_16.2: type = converted %T.ref, %T.as_type.loc11_16.1 [symbolic = %T.as_type.loc11_16.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @A.%T.as_type.loc11_16.2 (%T.as_type) = bind_name t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.decl: %B.type = fn_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @ImplicitAs(imports.%Core.import_ref.f6b058.1: type) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt (constants.%T.patt.e01)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.d62)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.519)] +// CHECK:STDOUT: %Convert.type: type = fn_type @Convert, @ImplicitAs(%T) [symbolic = %Convert.type (constants.%Convert.type.275)] +// CHECK:STDOUT: %Convert: @ImplicitAs.%Convert.type (%Convert.type.275) = struct_value () [symbolic = %Convert (constants.%Convert.42e)] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.837)] +// CHECK:STDOUT: %assoc0: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.837) = assoc_entity element0, imports.%Core.import_ref.207961.1 [symbolic = %assoc0 (constants.%assoc0.43db8b.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Core.import_ref.ff5 +// CHECK:STDOUT: .Convert = imports.%Core.import_ref.630 +// CHECK:STDOUT: witness = (imports.%Core.Convert) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @impl(%T.loc9_14.1: type) { +// CHECK:STDOUT: %T.loc9_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] +// CHECK:STDOUT: %T.patt.loc9_14.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_14.2 (constants.%T.patt.e01)] +// CHECK:STDOUT: %C.loc9_31.2: type = class_type @C, @C(%T.loc9_14.2, constants.%empty_tuple.type) [symbolic = %C.loc9_31.2 (constants.%C.463)] +// CHECK:STDOUT: %impl_witness: = impl_witness (), @impl(%T.loc9_14.2) [symbolic = %impl_witness (constants.%impl_witness.1a1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: impl: %C.loc9_31.1 as %I.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(%V.loc7_9.1: type, %W.loc7_19.1: type) { +// CHECK:STDOUT: %V.loc7_9.2: type = bind_symbolic_name V, 0 [symbolic = %V.loc7_9.2 (constants.%V)] +// CHECK:STDOUT: %V.patt.loc7_9.2: type = symbolic_binding_pattern V, 0 [symbolic = %V.patt.loc7_9.2 (constants.%V.patt)] +// CHECK:STDOUT: %W.loc7_19.2: type = bind_symbolic_name W, 1 [symbolic = %W.loc7_19.2 (constants.%W)] +// CHECK:STDOUT: %W.patt.loc7_19.2: type = symbolic_binding_pattern W, 1 [symbolic = %W.patt.loc7_19.2 (constants.%W.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.c6b +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A(%T.loc11_6.1: %I.type) { +// CHECK:STDOUT: %T.loc11_6.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc11_6.2 (constants.%T.826)] +// CHECK:STDOUT: %T.patt.loc11_6.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt.3ad)] +// CHECK:STDOUT: %T.as_type.loc11_16.2: type = facet_access_type %T.loc11_6.2 [symbolic = %T.as_type.loc11_16.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @A.%T.as_type.loc11_16.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %I.type](%t.param_patt: @A.%T.as_type.loc11_16.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %.loc24_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] +// CHECK:STDOUT: %.loc24_14: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc24_18: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc24_19.1: type = converted %.loc24_14, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc24_19.2: type = converted %.loc24_18, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %C: type = class_type @C, @C(constants.%empty_struct_type, constants.%empty_struct_type) [concrete = constants.%C.c74] +// CHECK:STDOUT: %.loc24_6.2: ref %C.c74 = temporary_storage +// CHECK:STDOUT: %.loc24_6.3: init %C.c74 = class_init (), %.loc24_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc24_6.4: ref %C.c74 = temporary %.loc24_6.2, %.loc24_6.3 +// CHECK:STDOUT: %.loc24_8: ref %C.c74 = converted %.loc24_6.1, %.loc24_6.4 +// CHECK:STDOUT: %.loc24_20: %I.type = converted constants.%C.c74, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Convert(imports.%Core.import_ref.f6b058.2: type, imports.%Core.import_ref.ce1: @ImplicitAs.%ImplicitAs.type (%ImplicitAs.type.d62)) [from "core.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%T)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.d62)] +// CHECK:STDOUT: %Self: %ImplicitAs.type.d62 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.519)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @Convert.%Self.as_type (%Self.as_type)]() -> @Convert.%T (%T.8b3); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%V, constants.%W) { +// CHECK:STDOUT: %V.loc7_9.2 => constants.%V +// CHECK:STDOUT: %V.patt.loc7_9.2 => constants.%V +// CHECK:STDOUT: %W.loc7_19.2 => constants.%W +// CHECK:STDOUT: %W.patt.loc7_19.2 => constants.%W +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%T.8b3, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc7_9.2 => constants.%T.8b3 +// CHECK:STDOUT: %V.patt.loc7_9.2 => constants.%T.8b3 +// CHECK:STDOUT: %W.loc7_19.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc7_19.2 => constants.%empty_tuple.type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%T.8b3) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%T.8b3 +// CHECK:STDOUT: %C.loc9_31.2 => constants.%C.463 +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.1a1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(@impl.%T.loc9_14.2, constants.%empty_tuple.type) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(%T.loc9_14.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A(constants.%T.826) { +// CHECK:STDOUT: %T.loc11_6.2 => constants.%T.826 +// CHECK:STDOUT: %T.patt.loc11_6.2 => constants.%T.826 +// CHECK:STDOUT: %T.as_type.loc11_16.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%empty_struct_type, constants.%empty_struct_type) { +// CHECK:STDOUT: %V.loc7_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: %V.patt.loc7_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.loc7_19.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.patt.loc7_19.2 => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @impl(constants.%empty_struct_type) { +// CHECK:STDOUT: %T.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %T.patt.loc9_14.2 => constants.%empty_struct_type +// CHECK:STDOUT: %C.loc9_31.2 => constants.%C.83b +// CHECK:STDOUT: %impl_witness => constants.%impl_witness.366 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%empty_struct_type, constants.%empty_tuple.type) { +// CHECK:STDOUT: %V.loc7_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: %V.patt.loc7_9.2 => constants.%empty_struct_type +// CHECK:STDOUT: %W.loc7_19.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %W.patt.loc7_19.2 => constants.%empty_tuple.type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %T.patt => constants.%T.8b3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(@Convert.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Convert(constants.%T.8b3, constants.%Self.519) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.d62 +// CHECK:STDOUT: %Self => constants.%Self.519 +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @ImplicitAs(constants.%I.type) { +// CHECK:STDOUT: %T => constants.%I.type +// CHECK:STDOUT: %T.patt => constants.%I.type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %ImplicitAs.type => constants.%ImplicitAs.type.c42 +// CHECK:STDOUT: %Self => constants.%Self.519 +// CHECK:STDOUT: %Convert.type => constants.%Convert.type.7ef +// CHECK:STDOUT: %Convert => constants.%Convert.c77 +// CHECK:STDOUT: %ImplicitAs.assoc_type => constants.%ImplicitAs.assoc_type.167 +// CHECK:STDOUT: %assoc0 => constants.%assoc0.ae9 // CHECK:STDOUT: } // CHECK:STDOUT: