Files
carbon-lang/toolchain/check/testdata/interface/observe.carbon
Dana Jansens 9fb428d713 Ensure specific in ImplWitness has resolved definition before accessing witness table (#8040)
When impl lookup results in an `ImplWitness`, either directly or later
through `LookupImplWitness` evaluating to an `ImplWitness` inside some
specific, it represents a dependency on the eval blocks of the
`ImplDecl` that the `ImplWitness` comes from. The `ImplWitness` contains
a `SpecificId` of the `ImplDecl`, and the constants in the witness table
must be viewed through that `SpecificId`. The constants may depend on
the declaration or the definition block of the `ImplDecl`'s specific, so
any use of the witness table from `ImplWitness` requires the specific
from the `ImplWitness` to be fully resolved: both the decl and
definition blocks.

The specific declaration block is always resolved immediately when
forming a specific id, so there's nothing to do there. And things are
simple when the `ImplWitness` returned from impl lookup is concrete. We
would simply resolve the specific definition directly in the evaluation
of `LookupImplWitness`.

But when the `ImplWitness` is symbolic, meaning there's a dependency on
generic parameters in its referenced specific, then we have a dependency
on resolving the specific definition in the `ImplWitness` for every
specific that gets applied to the `ImplWitness`, eventually resulting in
a concrete specific.

Previously we attempted to do this by representing a dependency edge
from the eval block containing the `ImplWitness` instruction to the
definition block of the specific inside the `ImplWitness`. We
represented this dependency edge with the `RequireSpecificDefinition`
instruction.

The challenge with the `RequireSpecificDefinition` instruction was
ensuring it always landed in the _same eval block_ as the one holding
the symbolic `ImplWitness`. Ultimately, we've found a way to do this
without the `RequireSpecificDefinition`. The witness table is accessed
through `ImplWitnessAccess`, so we resolve the specific definition
before each access to the witness table. If the definition is already
resolved, this just costs a lookup of the Specific from the value store.

We document the other things we tried, which don't work or were too
complex, below.

In PR #6236, we added the `RequireSpecificDefinition` instruction in the
eval of `LookupImplWitness`, but this is too late. If impl lookup
resolved to a symbolic `LookupImplWitness`, the `LookupImplWitness` is
added some eval block. Later, we form specifics and re-evaluate that
eval block, and the `LookupImplWitness` can evaluate to an
`ImplWitness`. Adding the `RequireSpecificDefinition` instruction at
this point inserts the instruction into whatever generic's eval block
happens to be on the top of the generic stack, not the eval block of the
generic we are building a specific for. And indeed we can't add
instructions to a generic's eval block later like this, as it would be
missing from specifics that were already resolved for the generic. This
incorrect insertion shows up as a crash in eval at the CHECK introduced
but commented out in [eval.cpp in
#7981](https://github.com/carbon-language/carbon-lang/blob/56d9bbc40add1e9263f2f9b2555c3a27292d1725/toolchain/check/eval.cpp#L3507-L3512).
This is covered by the
`require_specific_impl_definition_through_specific_instantiation.carbon`
test.

We tried moving the insertion of `RequireSpecificDefinition` to be
earlier - at the point where the `LookupImplWitness` is constructed, in
the `LookupImplWitness()` function, instead of inside evaluation. This
seemed like a straightforwardly correct answer, as the eval block that
contains the `LookupImplWitness` will then also contain the
`RequireSpecificDefinition`. However, this can cause us to lose the
`RequireSpecificDefinition` entirely. Because it's a separate
instruction, not an operand of `LookupImplWitness`, it does not get
treated as a dependency of the witness. When we do an impl lookup inside
an `alias`, we build a generic for the alias and then discard it. This
discards the eval block containing the `LookupImplWitness`. Then, in an
enclosing generic, we refer to the constructed `AliasDecl` instruction,
which pulls all its dependent operands into the enclosing eval block.
This pulls in the `LookupImplWitness` into the enclosing eval block, but
it does not preserve the `RequireSpecificDefinition`. This is covered by
the
`require_specific_impl_definition_from_lookup_impl_witness_in_class_definition.carbon`
test.

We tried having `ImplWitness` evaluation resolve the specific definition
of the specific `ImplDecl` it refers to. This seems like the simplest
approach by far as we should always be working with the correct eval
block and nothing can get lost. However it does not work because of the
recursive nature of `ImplWitness`. The `ImplWitness` instruction appears
in the declaration of an `ImplDecl`, and the `ImplWitness` holds a
`SpecificId` for that same `ImplDecl`. When building a specific
`ImplDecl`, we evaluate the `ImplWitness` in the `ImplDecl`'s
declaration block which then immediately resolves the specific
definition before the declaration is finished. This leads to missing
instructions in the specific definition. In short, this puts the
dependency edge to the `ImplDecl`'s specific inside the `ImplDecl`
itself, which is problematic.

We tried wrapping `ImplWitness` in another instruction,
`ImplWitnessUse`. Inside the `ImplDecl` declaration there is still
`ImplWitness`, but then in the definition there is `ImplWitnessUse` and
that is what is returned from the evaluation of `LookupImplWitness`. The
`ImplWitnessUse` is an `ImplWitness` plus it ensures the specific
referred to by the witness has its definition resolved. However this
breaks constant comparisons, as we get different witnesses inside an
impl versus outside.

The first iteration of this PR's solution had us insert the
`RequireSpecificDefinition` into the eval block when we sniffed a
`LookupImplWitness` instruction, however that missed cases where impl
lookup immediately resolved to a symbolic `ImplWitness`, which is why we
now sniff for the `ImplWitness` in the eval block. This is covered by
the
`require_specific_impl_definition_from_symbolic_impl_in_class_definition.carbon`
test.

We also originally made a mistake of not inserting
`RequireSpecificDefinition` when inside the impl definition that the
`ImplWitness` refers to. But we can form specifics ImplWitness values
through function signatures, and these must add the dependency edge on
that specific ImplDecl definition. This is covered by the
`require_specific_impl_definition_from_inside_impl_definition.carbon`
test.

Finally, we did have a working solution. It was to sniff instructions
added to the eval block of a generic, and when an `ImplWitness` is added
to the eval block (it is implied that it is symbolic), also add a
`RequireSpecificDefinition` to that eval block immediately. We also
resolved the definition of a specific referred to by `ImplWitness` when
`LookupImplWitness` evaluates to `ImplWitness` to cover the concrete
witness case. This complicated the construction of the eval block
immensely, however. It caused a situation where adding one inst to the
eval block actually adds two, which we needed to avoid when importing.
And it required inst-kind specific behaviour in the very general
construction of an eval block, completely outside of eval itself.
2026-11-03 14:15:14 +00:00

1211 lines
85 KiB
Plaintext

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/observe.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/observe.carbon
// --- transitive.carbon
library "[[@TEST_NAME]]";
interface P { fn InP(self); }
interface Q { fn InQ(self); }
interface R { fn InR(self); }
//@dump-sem-ir-begin
interface Transitive {
let A: P & Core.Destroy;
let B: (Q where .Self == A) & Core.Destroy;
let C: (R where .Self == B) & Core.Destroy;
fn GetA(self) -> A;
fn TakesC(self, c: C);
observe A == B == C;
}
//@dump-sem-ir-end
// --- fail_todo_equivalent.carbon
library "[[@TEST_NAME]]";
import library "transitive";
fn F[T: Transitive](t: T) {
var a: T.A = t.GetA();
// CHECK:STDERR: fail_todo_equivalent.carbon:[[@LINE+3]]:3-13: error: cannot convert type `T.(Transitive.A)` that implements `P & Core.Destroy` into type implementing `R & Core.Destroy where...` [ConversionFailureFacetToFacet]
// CHECK:STDERR: transitive.carbon:14:3-24: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
t.TakesC(a);
// CHECK:STDERR: fail_todo_equivalent.carbon:[[@LINE+3]]:4-11: error: cannot convert expression of type `T.(Transitive.A)` to `T.(Transitive.C)` with `as` [ConversionFailure]
// CHECK:STDERR: fail_todo_equivalent.carbon:[[@LINE+2]]:4-11: note: type `T.(Transitive.A)` does not implement interface `Core.As(T.(Transitive.C))` [MissingImplInMemberAccessInContext]
// CHECK:STDERR:
(a as T.C).InR();
}
// --- fail_todo_impls.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B { require impls A; }
interface C { require impls B; }
fn RequiresA[T: A](unused x: T) {}
fn F[T: C](x: T) {
observe T impls B;
// CHECK:STDERR: fail_todo_impls.carbon:[[@LINE+3]]:3-14: error: cannot convert type `T` that implements `C` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_todo_impls.carbon:[[@LINE-5]]:1-33: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
RequiresA(x);
}
// --- fail_todo_equivalent_impls.carbon
library "[[@TEST_NAME]]";
import library "transitive";
fn TakesPQR[U: P & Q & R](unused u: U) {}
fn G[T: Transitive](t: T) {
var a: T.A = t.GetA();
observe T.A == T.B impls Q;
// CHECK:STDERR: fail_todo_equivalent_impls.carbon:[[@LINE+2]]:3-11: error: cannot access member of interface `Q` in type `T.(Transitive.A)` that does not implement that interface [MissingImplInMemberAccess]
// CHECK:STDERR:
a.(Q.InQ)();
observe T.A == T.C impls R;
// CHECK:STDERR: fail_todo_equivalent_impls.carbon:[[@LINE+3]]:3-13: error: cannot convert type `T.(Transitive.A)` that implements `P & Core.Destroy` into type implementing `P & Q & R` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_todo_equivalent_impls.carbon:[[@LINE-11]]:1-40: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesPQR(a);
}
// --- fail_equivalent_impls_without_observe.carbon
library "[[@TEST_NAME]]";
import library "transitive";
fn TakesPQR[U: P & Q & R](unused u: U) {}
fn G[T: Transitive](t: T) {
var a: T.A = t.GetA();
// CHECK:STDERR: fail_equivalent_impls_without_observe.carbon:[[@LINE+2]]:3-11: error: cannot access member of interface `Q` in type `T.(Transitive.A)` that does not implement that interface [MissingImplInMemberAccess]
// CHECK:STDERR:
a.(Q.InQ)();
// CHECK:STDERR: fail_equivalent_impls_without_observe.carbon:[[@LINE+3]]:3-13: error: cannot convert type `T.(Transitive.A)` that implements `P & Core.Destroy` into type implementing `P & Q & R` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_equivalent_impls_without_observe.carbon:[[@LINE-9]]:1-40: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesPQR(a);
}
// --- blanket_impls.carbon
library "[[@TEST_NAME]]";
interface A { }
interface B { }
interface C { }
interface D { }
impl forall [T: A] T as B { }
impl forall [T: B] T as C { }
impl forall [T: C] T as D { }
fn RequiresB[T: B](unused x: T) {}
fn RequiresD[T: D](unused x: T) {}
//@dump-sem-ir-begin
fn RequiresA[T: A](x: T) {
RequiresB(x);
observe T impls B;
observe T impls C;
RequiresD(x);
}
//@dump-sem-ir-end
// --- fail_todo_observe_from_type_of_assoc_constant.carbon
library "[[@TEST_NAME]]";
import library "transitive";
interface Z {
// Transitive contains an observe statement which we use through `Z1`.
let Z1: Transitive;
}
fn F[U: Z](t: U.Z1) {
var a: U.Z1.A = t.GetA();
// Depends on the observe statement in Transitive, which is the type of `Z1`.
// CHECK:STDERR: fail_todo_observe_from_type_of_assoc_constant.carbon:[[@LINE+3]]:3-13: error: cannot convert type `U.(Z.Z1).(Transitive.A)` that implements `P & Core.Destroy` into type implementing `R & Core.Destroy where...` [ConversionFailureFacetToFacet]
// CHECK:STDERR: transitive.carbon:14:3-24: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
t.TakesC(a);
// CHECK:STDERR: fail_todo_observe_from_type_of_assoc_constant.carbon:[[@LINE+2]]:9-11: error: member name `T` not found in `Z` [MemberNameNotFoundInSpecificScope]
// CHECK:STDERR:
(a as U.T.C).InR();
}
// --- fail_todo_observe_nested_associated_constants.carbon
library "[[@TEST_NAME]]";
interface Z {
let A: Core.Destroy;
let B: (type where .Self == A) & Core.Destroy;
let C: (type where .Self == B) & Core.Destroy;
fn GetA(self) -> A;
fn TakesC(self, c: C);
}
interface Y {
let Y1: Z;
// Observes in an interface about associated constants in an associated
// constant. This is allowed in this scope since `Y1`, which is named in this
// scope, is present in all of the observed names
observe Y1.A == Y1.B == Y1.C;
}
fn F[T: Y](t: T.Y1) {
var a: T.Y1.A = t.GetA();
// CHECK:STDERR: fail_todo_observe_nested_associated_constants.carbon:[[@LINE+3]]:3-13: error: cannot convert type `T.(Y.Y1).(Z.A)` that implements `Core.Destroy` into type implementing `Core.Destroy where...` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_todo_observe_nested_associated_constants.carbon:[[@LINE-16]]:3-24: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
t.TakesC(a);
}
// --- fail_todo_nested_functions_in_outer.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
//@dump-sem-ir-begin
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B where .Self == T, V: C where .Self == U]() {
observe T == U == V;
fn InnerF(x: V) {
// CHECK:STDERR: fail_todo_nested_functions_in_outer.carbon:[[@LINE+3]]:5-13: error: cannot convert type `V` that implements `C where...` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_todo_nested_functions_in_outer.carbon:[[@LINE-6]]:1-30: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesA(x);
}
}
//@dump-sem-ir-end
// --- fail_todo_nested_functions_in_inner.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B where .Self == T, V: C where .Self == U]() {
fn InnerF(x: V) {
observe T == U == V;
// CHECK:STDERR: fail_todo_nested_functions_in_inner.carbon:[[@LINE+3]]:5-13: error: cannot convert type `V` that implements `C where...` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_todo_nested_functions_in_inner.carbon:[[@LINE-6]]:1-30: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesA(x);
}
}
// --- fail_nested_functions_lexical_order.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B where .Self == T, V: C where .Self == U]() {
fn InnerF(x: V) {
// CHECK:STDERR: fail_nested_functions_lexical_order.carbon:[[@LINE+3]]:5-13: error: cannot convert type `V` that implements `C where...` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_nested_functions_lexical_order.carbon:[[@LINE-5]]:1-30: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesA(x);
}
observe T == U == V;
}
// --- fail_nested_functions_leak_upward.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B where .Self == T, V: C where .Self == U](x: V) {
fn InnerF() {
observe T == U == V;
}
// CHECK:STDERR: fail_nested_functions_leak_upward.carbon:[[@LINE+3]]:3-11: error: cannot convert type `V` that implements `C where...` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_nested_functions_leak_upward.carbon:[[@LINE-8]]:1-30: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesA(x);
}
// --- fail_not_observed.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B where .Self == T, V: C where .Self == U](x: V) {
observe T == U;
// CHECK:STDERR: fail_not_observed.carbon:[[@LINE+2]]:3-11: error: name `RequiresA` not found [NameNotFound]
// CHECK:STDERR:
RequiresA(x);
}
// --- fail_invalid_equivalent.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
fn TakesA[T: A](unused x: T) {}
fn F[T: A, U: B](x: U) {
observe T == U;
// CHECK:STDERR: fail_invalid_equivalent.carbon:[[@LINE+3]]:3-11: error: cannot convert type `U` that implements `B` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: fail_invalid_equivalent.carbon:[[@LINE-4]]:1-30: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
TakesA(x);
}
// --- todo_fail_not_equivalent.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
fn F(generic T: A, generic U: B) {
// TODO: This should be diagnosed, since T and U are not equal by a
// single same-type `where` equality constraint.
observe T == U;
}
// --- interface_assoc_const_equivalent_to_external_type.carbon
library "[[@TEST_NAME]]";
class C;
interface A {
let A1: type where .Self == C;
observe A1 == C;
}
// --- interface_generic_param_equivalent_to_external_type.carbon
library "[[@TEST_NAME]]";
class C;
interface A(T: type where .Self == C) {
observe T == C;
}
// --- interface_enclosing_generic_param_equivalent_to_external_type.carbon
library "[[@TEST_NAME]]";
class C;
class D(T: type where .Self == C) {
interface A {
observe T == C;
}
}
// --- interface_generic_self_equivalent_to_external_type.carbon
library "[[@TEST_NAME]]";
class C;
interface A {
let A1: type where .Self == Self and .Self == C;
observe A1 == Self == C;
}
// --- todo_fail_interface_makes_external_equivalence.carbon
library "[[@TEST_NAME]]";
class C;
interface A {
let A1: type where .Self == C;
// TODO: This should be diagnosed, even though it is true, as `C` is not
// dependent on `Self`, on a generic parameter, nor an associated
// constant. All but one type must be.
observe A == C == C;
}
// --- fail_wrong_scope_class.carbon
library "[[@TEST_NAME]]";
class C(T: type, U: type) {
// CHECK:STDERR: fail_wrong_scope_class.carbon:[[@LINE+2]]:3-9: error: `observe` can only be used in an `interface` or `function` [ObserveInWrongScope]
// CHECK:STDERR:
observe T == U;
}
// --- fail_wrong_scope_named_constraint.carbon
library "[[@TEST_NAME]]";
constraint C(T: type, U: type) {
// CHECK:STDERR: fail_wrong_scope_named_constraint.carbon:[[@LINE+2]]:3-9: error: `observe` can only be used in an `interface` or `function` [ObserveInWrongScope]
// CHECK:STDERR:
observe T == U;
}
// --- fail_non_facet_type_in_impls.carbon
library "[[@TEST_NAME]]";
class C {}
interface A {}
fn F[T: A]() {
// CHECK:STDERR: fail_non_facet_type_in_impls.carbon:[[@LINE+2]]:19: error: right argument of `impls` requirement must be a facet type [ImplsOnNonFacetType]
// CHECK:STDERR:
observe T impls C;
}
// --- generic_observe.carbon
library "[[@TEST_NAME]]";
interface A {}
interface B {}
interface C {}
//@dump-sem-ir-begin
interface I(T: A) {
let U: (B where .Self == T) & Core.Destroy;
let V: (C where .Self == U) & Core.Destroy;
fn GetV(self) -> V;
fn TakesT(self, t: T);
observe T == U == V;
}
//@dump-sem-ir-end
// --- fail_todo_generic_import.carbon
library "[[@TEST_NAME]]";
import library "generic_observe";
fn F[W: A, X: I(W)](x: X) {
var v: X.V = x.GetV();
// CHECK:STDERR: fail_todo_generic_import.carbon:[[@LINE+3]]:3-13: error: cannot convert type `X.(I(W).V)` that implements `C & Core.Destroy where...` into type implementing `A` [ConversionFailureFacetToFacet]
// CHECK:STDERR: generic_observe.carbon:12:3-24: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR:
x.TakesT(v);
}
// CHECK:STDOUT: --- transitive.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Transitive.type: type = facet_type <@Transitive> [concrete]
// CHECK:STDOUT: %Self.77c: %Transitive.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %facet_type.6ce: type = facet_type <@P & @Destroy> [concrete]
// CHECK:STDOUT: %Transitive.assoc_type: type = assoc_entity_type @Transitive [concrete]
// CHECK:STDOUT: %assoc0.c48: %Transitive.assoc_type = assoc_entity element0, @Transitive.WithSelf.%A [concrete]
// CHECK:STDOUT: %Transitive.lookup_impl_witness: <witness> = lookup_impl_witness %Self.77c, @Transitive [symbolic]
// CHECK:STDOUT: %impl.elem0: %facet_type.6ce = impl_witness_access %Transitive.lookup_impl_witness, element0 [symbolic]
// CHECK:STDOUT: %facet_type.40a: type = facet_type <@Q & @Destroy where TODO> [concrete]
// CHECK:STDOUT: %assoc1: %Transitive.assoc_type = assoc_entity element1, @Transitive.WithSelf.%B [concrete]
// CHECK:STDOUT: %impl.elem1: %facet_type.40a = impl_witness_access %Transitive.lookup_impl_witness, element1 [symbolic]
// CHECK:STDOUT: %facet_type.afd: type = facet_type <@R & @Destroy where TODO> [concrete]
// CHECK:STDOUT: %assoc2: %Transitive.assoc_type = assoc_entity element2, @Transitive.WithSelf.%C [concrete]
// CHECK:STDOUT: %Self.as_type.7f2: type = facet_access_type %Self.77c [symbolic]
// CHECK:STDOUT: %pattern_type.b5c: type = pattern_type %Self.as_type.7f2 [symbolic]
// CHECK:STDOUT: %self.param_patt.ae9: %pattern_type.b5c = value_param_pattern [symbolic]
// CHECK:STDOUT: %self.patt.03f: %pattern_type.b5c = wrapper_binding_pattern self, %self.param_patt.ae9 [symbolic]
// CHECK:STDOUT: %as_type.e89: type = facet_access_type %impl.elem0 [symbolic]
// CHECK:STDOUT: %.33f: Core.Form = init_form %as_type.e89 [symbolic]
// CHECK:STDOUT: %pattern_type.46d: type = pattern_type %as_type.e89 [symbolic]
// CHECK:STDOUT: %return.param_patt.758: %pattern_type.46d = out_param_pattern [symbolic]
// CHECK:STDOUT: %return.patt.917: %pattern_type.46d = return_slot_pattern %return.param_patt.758, %as_type.e89 [symbolic]
// CHECK:STDOUT: %Transitive.WithSelf.GetA.type: type = fn_type @Transitive.WithSelf.GetA, @Transitive.WithSelf(%Self.77c) [symbolic]
// CHECK:STDOUT: %Transitive.WithSelf.GetA: %Transitive.WithSelf.GetA.type = struct_value () [symbolic]
// CHECK:STDOUT: %assoc3: %Transitive.assoc_type = assoc_entity element3, @Transitive.WithSelf.%Transitive.WithSelf.GetA.decl [concrete]
// CHECK:STDOUT: %impl.elem2: %facet_type.afd = impl_witness_access %Transitive.lookup_impl_witness, element2 [symbolic]
// CHECK:STDOUT: %as_type.95b: type = facet_access_type %impl.elem2 [symbolic]
// CHECK:STDOUT: %pattern_type.95b: type = pattern_type %as_type.95b [symbolic]
// CHECK:STDOUT: %c.param_patt: %pattern_type.95b = value_param_pattern [symbolic]
// CHECK:STDOUT: %c.patt: %pattern_type.95b = wrapper_binding_pattern c, %c.param_patt [symbolic]
// CHECK:STDOUT: %Transitive.WithSelf.TakesC.type: type = fn_type @Transitive.WithSelf.TakesC, @Transitive.WithSelf(%Self.77c) [symbolic]
// CHECK:STDOUT: %Transitive.WithSelf.TakesC: %Transitive.WithSelf.TakesC.type = struct_value () [symbolic]
// CHECK:STDOUT: %assoc4: %Transitive.assoc_type = assoc_entity element4, @Transitive.WithSelf.%Transitive.WithSelf.TakesC.decl [concrete]
// CHECK:STDOUT: %as_type.a97: type = facet_access_type %impl.elem1 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %Transitive.decl: type = interface_decl @Transitive [concrete = constants.%Transitive.type] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Transitive {
// CHECK:STDOUT: %Self: %Transitive.type = symbolic_binding Self, 0 [symbolic = constants.%Self.77c]
// CHECK:STDOUT: %Transitive.WithSelf.decl = interface_with_self_decl @Transitive [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !with Self:
// CHECK:STDOUT: %A: %facet_type.6ce = assoc_const_decl @A [concrete] {
// CHECK:STDOUT: %assoc0: %Transitive.assoc_type = assoc_entity element0, @Transitive.WithSelf.%A [concrete = constants.%assoc0.c48]
// CHECK:STDOUT: }
// CHECK:STDOUT: %B: %facet_type.40a = assoc_const_decl @B [concrete] {
// CHECK:STDOUT: %assoc1: %Transitive.assoc_type = assoc_entity element1, @Transitive.WithSelf.%B [concrete = constants.%assoc1]
// CHECK:STDOUT: }
// CHECK:STDOUT: %C: %facet_type.afd = assoc_const_decl @C [concrete] {
// CHECK:STDOUT: %assoc2: %Transitive.assoc_type = assoc_entity element2, @Transitive.WithSelf.%C [concrete = constants.%assoc2]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Transitive.WithSelf.GetA.decl: @Transitive.WithSelf.%Transitive.WithSelf.GetA.type (%Transitive.WithSelf.GetA.type) = fn_decl @Transitive.WithSelf.GetA [symbolic = @Transitive.WithSelf.%Transitive.WithSelf.GetA (constants.%Transitive.WithSelf.GetA)] {
// CHECK:STDOUT: %self.param_patt.loc13_11.1: @Transitive.WithSelf.GetA.%pattern_type.loc13_11 (%pattern_type.b5c) = value_param_pattern [symbolic = %self.param_patt.loc13_11.2 (constants.%self.param_patt.ae9)]
// CHECK:STDOUT: %self.patt.loc13_11.1: @Transitive.WithSelf.GetA.%pattern_type.loc13_11 (%pattern_type.b5c) = wrapper_binding_pattern self, %self.param_patt.loc13_11.1 [symbolic = %self.patt.loc13_11.2 (constants.%self.patt.03f)]
// CHECK:STDOUT: %return.param_patt.loc13_20.1: @Transitive.WithSelf.GetA.%pattern_type.loc13_20 (%pattern_type.46d) = out_param_pattern [symbolic = %return.param_patt.loc13_20.2 (constants.%return.param_patt.758)]
// CHECK:STDOUT: %return.patt.loc13_17.1: @Transitive.WithSelf.GetA.%pattern_type.loc13_20 (%pattern_type.46d) = return_slot_pattern %return.param_patt.loc13_20.1, %.loc13_20.2 [symbolic = %return.patt.loc13_17.2 (constants.%return.patt.917)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %impl.elem0.loc13_20.2: %facet_type.6ce = impl_witness_access constants.%Transitive.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc13_20.1 (constants.%impl.elem0)]
// CHECK:STDOUT: %A.ref: %facet_type.6ce = name_ref A, %impl.elem0.loc13_20.2 [symbolic = %impl.elem0.loc13_20.1 (constants.%impl.elem0)]
// CHECK:STDOUT: %A.as_type: type = facet_access_type %A.ref [symbolic = %as_type (constants.%as_type.e89)]
// CHECK:STDOUT: %.loc13_20.2: type = converted %A.ref, %A.as_type [symbolic = %as_type (constants.%as_type.e89)]
// CHECK:STDOUT: %.loc13_20.3: Core.Form = init_form %.loc13_20.2 [symbolic = %.loc13_20.1 (constants.%.33f)]
// CHECK:STDOUT: %self.param: @Transitive.WithSelf.GetA.%Self.as_type.loc13_11.1 (%Self.as_type.7f2) = value_param call_param0
// CHECK:STDOUT: %.loc13_11.1: type = splice_block %.loc13_11.2 [symbolic = %Self.as_type.loc13_11.1 (constants.%Self.as_type.7f2)] {
// CHECK:STDOUT: %Self.ref: %Transitive.type = name_ref Self, @Transitive.%Self [symbolic = %Self (constants.%Self.77c)]
// CHECK:STDOUT: %Self.as_type.loc13_11.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc13_11.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: %.loc13_11.2: type = converted %Self.ref, %Self.as_type.loc13_11.2 [symbolic = %Self.as_type.loc13_11.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %self: @Transitive.WithSelf.GetA.%Self.as_type.loc13_11.1 (%Self.as_type.7f2) = wrapper_binding self, %self.param
// CHECK:STDOUT: %return.param: ref @Transitive.WithSelf.GetA.%as_type (%as_type.e89) = out_param call_param1
// CHECK:STDOUT: %return: ref @Transitive.WithSelf.GetA.%as_type (%as_type.e89) = return_slot %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %assoc3: %Transitive.assoc_type = assoc_entity element3, %Transitive.WithSelf.GetA.decl [concrete = constants.%assoc3]
// CHECK:STDOUT: %Transitive.WithSelf.TakesC.decl: @Transitive.WithSelf.%Transitive.WithSelf.TakesC.type (%Transitive.WithSelf.TakesC.type) = fn_decl @Transitive.WithSelf.TakesC [symbolic = @Transitive.WithSelf.%Transitive.WithSelf.TakesC (constants.%Transitive.WithSelf.TakesC)] {
// CHECK:STDOUT: %self.param_patt.loc14_13.1: @Transitive.WithSelf.TakesC.%pattern_type.loc14_13 (%pattern_type.b5c) = value_param_pattern [symbolic = %self.param_patt.loc14_13.2 (constants.%self.param_patt.ae9)]
// CHECK:STDOUT: %self.patt.loc14_13.1: @Transitive.WithSelf.TakesC.%pattern_type.loc14_13 (%pattern_type.b5c) = wrapper_binding_pattern self, %self.param_patt.loc14_13.1 [symbolic = %self.patt.loc14_13.2 (constants.%self.patt.03f)]
// CHECK:STDOUT: %c.param_patt.loc14_20.1: @Transitive.WithSelf.TakesC.%pattern_type.loc14_20 (%pattern_type.95b) = value_param_pattern [symbolic = %c.param_patt.loc14_20.2 (constants.%c.param_patt)]
// CHECK:STDOUT: %c.patt.loc14_20.1: @Transitive.WithSelf.TakesC.%pattern_type.loc14_20 (%pattern_type.95b) = wrapper_binding_pattern c, %c.param_patt.loc14_20.1 [symbolic = %c.patt.loc14_20.2 (constants.%c.patt)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: @Transitive.WithSelf.TakesC.%Self.as_type.loc14_13.1 (%Self.as_type.7f2) = value_param call_param0
// CHECK:STDOUT: %.loc14_13.1: type = splice_block %.loc14_13.2 [symbolic = %Self.as_type.loc14_13.1 (constants.%Self.as_type.7f2)] {
// CHECK:STDOUT: %Self.ref: %Transitive.type = name_ref Self, @Transitive.%Self [symbolic = %Self (constants.%Self.77c)]
// CHECK:STDOUT: %Self.as_type.loc14_13.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc14_13.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: %.loc14_13.2: type = converted %Self.ref, %Self.as_type.loc14_13.2 [symbolic = %Self.as_type.loc14_13.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %self: @Transitive.WithSelf.TakesC.%Self.as_type.loc14_13.1 (%Self.as_type.7f2) = wrapper_binding self, %self.param
// CHECK:STDOUT: %c.param: @Transitive.WithSelf.TakesC.%as_type (%as_type.95b) = value_param call_param1
// CHECK:STDOUT: %.loc14_22.1: type = splice_block %.loc14_22.2 [symbolic = %as_type (constants.%as_type.95b)] {
// CHECK:STDOUT: %impl.elem2.loc14_22.2: %facet_type.afd = impl_witness_access constants.%Transitive.lookup_impl_witness, element2 [symbolic = %impl.elem2.loc14_22.1 (constants.%impl.elem2)]
// CHECK:STDOUT: %C.ref: %facet_type.afd = name_ref C, %impl.elem2.loc14_22.2 [symbolic = %impl.elem2.loc14_22.1 (constants.%impl.elem2)]
// CHECK:STDOUT: %C.as_type: type = facet_access_type %C.ref [symbolic = %as_type (constants.%as_type.95b)]
// CHECK:STDOUT: %.loc14_22.2: type = converted %C.ref, %C.as_type [symbolic = %as_type (constants.%as_type.95b)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: @Transitive.WithSelf.TakesC.%as_type (%as_type.95b) = wrapper_binding c, %c.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %assoc4: %Transitive.assoc_type = assoc_entity element4, %Transitive.WithSelf.TakesC.decl [concrete = constants.%assoc4]
// CHECK:STDOUT: %impl.elem0.loc16_11.1: %facet_type.6ce = impl_witness_access constants.%Transitive.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc16_11.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %A.ref: %facet_type.6ce = name_ref A, %impl.elem0.loc16_11.1 [symbolic = %impl.elem0.loc16_11.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %impl.elem1.loc16_16.1: %facet_type.40a = impl_witness_access constants.%Transitive.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc16_16.2 (constants.%impl.elem1)]
// CHECK:STDOUT: %B.ref: %facet_type.40a = name_ref B, %impl.elem1.loc16_16.1 [symbolic = %impl.elem1.loc16_16.2 (constants.%impl.elem1)]
// CHECK:STDOUT: %B.as_type.loc16_16.1: type = facet_access_type %B.ref [symbolic = %as_type.loc16_16 (constants.%as_type.a97)]
// CHECK:STDOUT: %.loc16_16.1: type = converted %B.ref, %B.as_type.loc16_16.1 [symbolic = %as_type.loc16_16 (constants.%as_type.a97)]
// CHECK:STDOUT: %A.as_type: type = facet_access_type %A.ref [symbolic = %as_type.loc16_11 (constants.%as_type.e89)]
// CHECK:STDOUT: %.loc16_11: type = converted %A.ref, %A.as_type [symbolic = %as_type.loc16_11 (constants.%as_type.e89)]
// CHECK:STDOUT: %impl.elem2.loc16_21.1: %facet_type.afd = impl_witness_access constants.%Transitive.lookup_impl_witness, element2 [symbolic = %impl.elem2.loc16_21.2 (constants.%impl.elem2)]
// CHECK:STDOUT: %C.ref: %facet_type.afd = name_ref C, %impl.elem2.loc16_21.1 [symbolic = %impl.elem2.loc16_21.2 (constants.%impl.elem2)]
// CHECK:STDOUT: %C.as_type: type = facet_access_type %C.ref [symbolic = %as_type.loc16_21 (constants.%as_type.95b)]
// CHECK:STDOUT: %.loc16_21: type = converted %C.ref, %C.as_type [symbolic = %as_type.loc16_21 (constants.%as_type.95b)]
// CHECK:STDOUT: %B.as_type.loc16_16.2: type = facet_access_type %B.ref [symbolic = %as_type.loc16_16 (constants.%as_type.a97)]
// CHECK:STDOUT: %.loc16_16.2: type = converted %B.ref, %B.as_type.loc16_16.2 [symbolic = %as_type.loc16_16 (constants.%as_type.a97)]
// CHECK:STDOUT: %Transitive.observe.decl = observe_decl @Transitive.observe [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: .P = <poisoned>
// CHECK:STDOUT: .Q = <poisoned>
// CHECK:STDOUT: .R = <poisoned>
// CHECK:STDOUT: .P = <poisoned>
// CHECK:STDOUT: .A = @A.%assoc0
// CHECK:STDOUT: .Q = <poisoned>
// CHECK:STDOUT: .B = @B.%assoc1
// CHECK:STDOUT: .R = <poisoned>
// CHECK:STDOUT: .C = @C.%assoc2
// CHECK:STDOUT: .GetA = @Transitive.WithSelf.%assoc3
// CHECK:STDOUT: .TakesC = @Transitive.WithSelf.%assoc4
// CHECK:STDOUT: witness = (@Transitive.WithSelf.%A, @Transitive.WithSelf.%B, @Transitive.WithSelf.%C, @Transitive.WithSelf.%Transitive.WithSelf.GetA.decl, @Transitive.WithSelf.%Transitive.WithSelf.TakesC.decl)
// CHECK:STDOUT:
// CHECK:STDOUT: !requires:
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: @Transitive.observe {
// CHECK:STDOUT: observe constants.%impl.elem0 == constants.%impl.elem1 == constants.%impl.elem2
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Transitive.WithSelf.GetA(@Transitive.%Self: %Transitive.type) {
// CHECK:STDOUT: %Self: %Transitive.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.77c)]
// CHECK:STDOUT: %Self.as_type.loc13_11.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc13_11.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: %pattern_type.loc13_11: type = pattern_type %Self.as_type.loc13_11.1 [symbolic = %pattern_type.loc13_11 (constants.%pattern_type.b5c)]
// CHECK:STDOUT: %self.param_patt.loc13_11.2: @Transitive.WithSelf.GetA.%pattern_type.loc13_11 (%pattern_type.b5c) = value_param_pattern [symbolic = %self.param_patt.loc13_11.2 (constants.%self.param_patt.ae9)]
// CHECK:STDOUT: %self.patt.loc13_11.2: @Transitive.WithSelf.GetA.%pattern_type.loc13_11 (%pattern_type.b5c) = wrapper_binding_pattern self, %self.param_patt.loc13_11.2 [symbolic = %self.patt.loc13_11.2 (constants.%self.patt.03f)]
// CHECK:STDOUT: %Transitive.lookup_impl_witness: <witness> = lookup_impl_witness %Self, @Transitive [symbolic = %Transitive.lookup_impl_witness (constants.%Transitive.lookup_impl_witness)]
// CHECK:STDOUT: %impl.elem0.loc13_20.1: %facet_type.6ce = impl_witness_access %Transitive.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc13_20.1 (constants.%impl.elem0)]
// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0.loc13_20.1 [symbolic = %as_type (constants.%as_type.e89)]
// CHECK:STDOUT: %.loc13_20.1: Core.Form = init_form %as_type [symbolic = %.loc13_20.1 (constants.%.33f)]
// CHECK:STDOUT: %pattern_type.loc13_20: type = pattern_type %as_type [symbolic = %pattern_type.loc13_20 (constants.%pattern_type.46d)]
// CHECK:STDOUT: %return.param_patt.loc13_20.2: @Transitive.WithSelf.GetA.%pattern_type.loc13_20 (%pattern_type.46d) = out_param_pattern [symbolic = %return.param_patt.loc13_20.2 (constants.%return.param_patt.758)]
// CHECK:STDOUT: %return.patt.loc13_17.2: @Transitive.WithSelf.GetA.%pattern_type.loc13_20 (%pattern_type.46d) = return_slot_pattern %return.param_patt.loc13_20.2, %as_type [symbolic = %return.patt.loc13_17.2 (constants.%return.patt.917)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%self.param: @Transitive.WithSelf.GetA.%Self.as_type.loc13_11.1 (%Self.as_type.7f2)) -> out %return.param: @Transitive.WithSelf.GetA.%as_type (%as_type.e89);
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Transitive.WithSelf.TakesC(@Transitive.%Self: %Transitive.type) {
// CHECK:STDOUT: %Self: %Transitive.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.77c)]
// CHECK:STDOUT: %Self.as_type.loc14_13.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc14_13.1 (constants.%Self.as_type.7f2)]
// CHECK:STDOUT: %pattern_type.loc14_13: type = pattern_type %Self.as_type.loc14_13.1 [symbolic = %pattern_type.loc14_13 (constants.%pattern_type.b5c)]
// CHECK:STDOUT: %self.param_patt.loc14_13.2: @Transitive.WithSelf.TakesC.%pattern_type.loc14_13 (%pattern_type.b5c) = value_param_pattern [symbolic = %self.param_patt.loc14_13.2 (constants.%self.param_patt.ae9)]
// CHECK:STDOUT: %self.patt.loc14_13.2: @Transitive.WithSelf.TakesC.%pattern_type.loc14_13 (%pattern_type.b5c) = wrapper_binding_pattern self, %self.param_patt.loc14_13.2 [symbolic = %self.patt.loc14_13.2 (constants.%self.patt.03f)]
// CHECK:STDOUT: %Transitive.lookup_impl_witness: <witness> = lookup_impl_witness %Self, @Transitive [symbolic = %Transitive.lookup_impl_witness (constants.%Transitive.lookup_impl_witness)]
// CHECK:STDOUT: %impl.elem2.loc14_22.1: %facet_type.afd = impl_witness_access %Transitive.lookup_impl_witness, element2 [symbolic = %impl.elem2.loc14_22.1 (constants.%impl.elem2)]
// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem2.loc14_22.1 [symbolic = %as_type (constants.%as_type.95b)]
// CHECK:STDOUT: %pattern_type.loc14_20: type = pattern_type %as_type [symbolic = %pattern_type.loc14_20 (constants.%pattern_type.95b)]
// CHECK:STDOUT: %c.param_patt.loc14_20.2: @Transitive.WithSelf.TakesC.%pattern_type.loc14_20 (%pattern_type.95b) = value_param_pattern [symbolic = %c.param_patt.loc14_20.2 (constants.%c.param_patt)]
// CHECK:STDOUT: %c.patt.loc14_20.2: @Transitive.WithSelf.TakesC.%pattern_type.loc14_20 (%pattern_type.95b) = wrapper_binding_pattern c, %c.param_patt.loc14_20.2 [symbolic = %c.patt.loc14_20.2 (constants.%c.patt)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%self.param: @Transitive.WithSelf.TakesC.%Self.as_type.loc14_13.1 (%Self.as_type.7f2), %c.param: @Transitive.WithSelf.TakesC.%as_type (%as_type.95b));
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Transitive.WithSelf(constants.%Self.77c) {}
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Transitive.WithSelf.GetA(constants.%Self.77c) {
// CHECK:STDOUT: %Self => constants.%Self.77c
// CHECK:STDOUT: %Self.as_type.loc13_11.1 => constants.%Self.as_type.7f2
// CHECK:STDOUT: %pattern_type.loc13_11 => constants.%pattern_type.b5c
// CHECK:STDOUT: %self.param_patt.loc13_11.2 => constants.%self.param_patt.ae9
// CHECK:STDOUT: %self.patt.loc13_11.2 => constants.%self.patt.03f
// CHECK:STDOUT: %Transitive.lookup_impl_witness => constants.%Transitive.lookup_impl_witness
// CHECK:STDOUT: %impl.elem0.loc13_20.1 => constants.%impl.elem0
// CHECK:STDOUT: %as_type => constants.%as_type.e89
// CHECK:STDOUT: %.loc13_20.1 => constants.%.33f
// CHECK:STDOUT: %pattern_type.loc13_20 => constants.%pattern_type.46d
// CHECK:STDOUT: %return.param_patt.loc13_20.2 => constants.%return.param_patt.758
// CHECK:STDOUT: %return.patt.loc13_17.2 => constants.%return.patt.917
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Transitive.WithSelf.TakesC(constants.%Self.77c) {
// CHECK:STDOUT: %Self => constants.%Self.77c
// CHECK:STDOUT: %Self.as_type.loc14_13.1 => constants.%Self.as_type.7f2
// CHECK:STDOUT: %pattern_type.loc14_13 => constants.%pattern_type.b5c
// CHECK:STDOUT: %self.param_patt.loc14_13.2 => constants.%self.param_patt.ae9
// CHECK:STDOUT: %self.patt.loc14_13.2 => constants.%self.patt.03f
// CHECK:STDOUT: %Transitive.lookup_impl_witness => constants.%Transitive.lookup_impl_witness
// CHECK:STDOUT: %impl.elem2.loc14_22.1 => constants.%impl.elem2
// CHECK:STDOUT: %as_type => constants.%as_type.95b
// CHECK:STDOUT: %pattern_type.loc14_20 => constants.%pattern_type.95b
// CHECK:STDOUT: %c.param_patt.loc14_20.2 => constants.%c.param_patt
// CHECK:STDOUT: %c.patt.loc14_20.2 => constants.%c.patt
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- blanket_impls.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete]
// CHECK:STDOUT: %C.type: type = facet_type <@C> [concrete]
// CHECK:STDOUT: %D.type: type = facet_type <@D> [concrete]
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.029: type = pattern_type %A.type [concrete]
// CHECK:STDOUT: %T.patt.a4b: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T.626: %A.type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %T.as_type.3b8: type = facet_access_type %T.626 [symbolic]
// CHECK:STDOUT: %RequiresB.type: type = fn_type @RequiresB [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %RequiresB: %RequiresB.type = struct_value () [concrete]
// CHECK:STDOUT: %RequiresD.type: type = fn_type @RequiresD [concrete]
// CHECK:STDOUT: %RequiresD: %RequiresD.type = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.a0e: type = pattern_type %T.as_type.3b8 [symbolic]
// CHECK:STDOUT: %x.param_patt.241: %pattern_type.a0e = value_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.cd4828.1: %pattern_type.a0e = wrapper_binding_pattern x, %x.param_patt.241 [symbolic]
// CHECK:STDOUT: %RequiresA.type: type = fn_type @RequiresA [concrete]
// CHECK:STDOUT: %RequiresA: %RequiresA.type = struct_value () [concrete]
// CHECK:STDOUT: %require_complete.94f: <witness> = require_complete_type %T.as_type.3b8 [symbolic]
// CHECK:STDOUT: %B.lookup_impl_witness: <witness> = lookup_impl_witness %T.626, @B [symbolic]
// CHECK:STDOUT: %B.facet.c85: %B.type = facet_value %T.as_type.3b8, (%B.lookup_impl_witness) [symbolic]
// CHECK:STDOUT: %RequiresB.specific_fn: <specific function> = specific_function %RequiresB, @RequiresB(%B.facet.c85) [symbolic]
// CHECK:STDOUT: %impls.be1 = observe_impls %T.626, %B.type [symbolic]
// CHECK:STDOUT: %impls.86f = observe_impls %T.626, %C.type [symbolic]
// CHECK:STDOUT: %D.lookup_impl_witness: <witness> = lookup_impl_witness %T.626, @D [symbolic]
// CHECK:STDOUT: %D.facet.5cf: %D.type = facet_value %T.as_type.3b8, (%D.lookup_impl_witness) [symbolic]
// CHECK:STDOUT: %RequiresD.specific_fn: <specific function> = specific_function %RequiresD, @RequiresD(%D.facet.5cf) [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %RequiresA.decl: %RequiresA.type = fn_decl @RequiresA [concrete = constants.%RequiresA] {
// CHECK:STDOUT: %T.patt.loc16_15.1: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc16_15.2 (constants.%T.patt.a4b)]
// CHECK:STDOUT: %x.param_patt.loc16_21.1: @RequiresA.%pattern_type (%pattern_type.a0e) = value_param_pattern [symbolic = %x.param_patt.loc16_21.2 (constants.%x.param_patt.241)]
// CHECK:STDOUT: %x.patt.loc16_21.1: @RequiresA.%pattern_type (%pattern_type.a0e) = wrapper_binding_pattern x, %x.param_patt.loc16_21.1 [symbolic = %x.patt.loc16_21.2 (constants.%x.patt.cd4828.1)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc16_17: type = splice_block %A.ref [concrete = constants.%A.type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc16_15.2: %A.type = symbolic_binding T, 0 [symbolic = %T.loc16_15.1 (constants.%T.626)]
// CHECK:STDOUT: %x.param: @RequiresA.%T.as_type.loc16_23.1 (%T.as_type.3b8) = value_param call_param0
// CHECK:STDOUT: %.loc16_23.1: type = splice_block %.loc16_23.2 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)] {
// CHECK:STDOUT: %T.ref.loc16: %A.type = name_ref T, %T.loc16_15.2 [symbolic = %T.loc16_15.1 (constants.%T.626)]
// CHECK:STDOUT: %T.as_type.loc16_23.2: type = facet_access_type %T.ref.loc16 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %.loc16_23.2: type = converted %T.ref.loc16, %T.as_type.loc16_23.2 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: @RequiresA.%T.as_type.loc16_23.1 (%T.as_type.3b8) = wrapper_binding x, %x.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @RequiresA(%T.loc16_15.2: %A.type) {
// CHECK:STDOUT: %T.patt.loc16_15.2: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc16_15.2 (constants.%T.patt.a4b)]
// CHECK:STDOUT: %T.loc16_15.1: %A.type = symbolic_binding T, 0 [symbolic = %T.loc16_15.1 (constants.%T.626)]
// CHECK:STDOUT: %T.as_type.loc16_23.1: type = facet_access_type %T.loc16_15.1 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %T.as_type.loc16_23.1 [symbolic = %pattern_type (constants.%pattern_type.a0e)]
// CHECK:STDOUT: %x.param_patt.loc16_21.2: @RequiresA.%pattern_type (%pattern_type.a0e) = value_param_pattern [symbolic = %x.param_patt.loc16_21.2 (constants.%x.param_patt.241)]
// CHECK:STDOUT: %x.patt.loc16_21.2: @RequiresA.%pattern_type (%pattern_type.a0e) = wrapper_binding_pattern x, %x.param_patt.loc16_21.2 [symbolic = %x.patt.loc16_21.2 (constants.%x.patt.cd4828.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.as_type.loc16_23.1 [symbolic = %require_complete (constants.%require_complete.94f)]
// CHECK:STDOUT: %B.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc16_15.1, @B [symbolic = %B.lookup_impl_witness (constants.%B.lookup_impl_witness)]
// CHECK:STDOUT: %B.facet.loc17_14.3: %B.type = facet_value %T.as_type.loc16_23.1, (%B.lookup_impl_witness) [symbolic = %B.facet.loc17_14.3 (constants.%B.facet.c85)]
// CHECK:STDOUT: %RequiresB.specific_fn.loc17_3.2: <specific function> = specific_function constants.%RequiresB, @RequiresB(%B.facet.loc17_14.3) [symbolic = %RequiresB.specific_fn.loc17_3.2 (constants.%RequiresB.specific_fn)]
// CHECK:STDOUT: %impls.loc19 = observe_impls %T.loc16_15.1, constants.%B.type [symbolic = %impls.loc19 (constants.%impls.be1)]
// CHECK:STDOUT: %impls.loc20 = observe_impls %T.loc16_15.1, constants.%C.type [symbolic = %impls.loc20 (constants.%impls.86f)]
// CHECK:STDOUT: %D.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc16_15.1, @D [symbolic = %D.lookup_impl_witness (constants.%D.lookup_impl_witness)]
// CHECK:STDOUT: %D.facet.loc21_14.3: %D.type = facet_value %T.as_type.loc16_23.1, (%D.lookup_impl_witness) [symbolic = %D.facet.loc21_14.3 (constants.%D.facet.5cf)]
// CHECK:STDOUT: %RequiresD.specific_fn.loc21_3.2: <specific function> = specific_function constants.%RequiresD, @RequiresD(%D.facet.loc21_14.3) [symbolic = %RequiresD.specific_fn.loc21_3.2 (constants.%RequiresD.specific_fn)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @RequiresA.%T.as_type.loc16_23.1 (%T.as_type.3b8)) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %RequiresB.ref: %RequiresB.type = name_ref RequiresB, file.%RequiresB.decl [concrete = constants.%RequiresB]
// CHECK:STDOUT: %x.ref.loc17: @RequiresA.%T.as_type.loc16_23.1 (%T.as_type.3b8) = name_ref x, %x
// CHECK:STDOUT: %B.facet.loc17_14.1: %B.type = facet_value constants.%T.as_type.3b8, (constants.%B.lookup_impl_witness) [symbolic = %B.facet.loc17_14.3 (constants.%B.facet.c85)]
// CHECK:STDOUT: %.loc17_14.1: %B.type = converted constants.%T.as_type.3b8, %B.facet.loc17_14.1 [symbolic = %B.facet.loc17_14.3 (constants.%B.facet.c85)]
// CHECK:STDOUT: %B.facet.loc17_14.2: %B.type = facet_value constants.%T.as_type.3b8, (constants.%B.lookup_impl_witness) [symbolic = %B.facet.loc17_14.3 (constants.%B.facet.c85)]
// CHECK:STDOUT: %.loc17_14.2: %B.type = converted constants.%T.as_type.3b8, %B.facet.loc17_14.2 [symbolic = %B.facet.loc17_14.3 (constants.%B.facet.c85)]
// CHECK:STDOUT: %RequiresB.specific_fn.loc17_3.1: <specific function> = specific_function %RequiresB.ref, @RequiresB(constants.%B.facet.c85) [symbolic = %RequiresB.specific_fn.loc17_3.2 (constants.%RequiresB.specific_fn)]
// CHECK:STDOUT: %RequiresB.call: init %empty_tuple.type = call %RequiresB.specific_fn.loc17_3.1(%x.ref.loc17)
// CHECK:STDOUT: %T.ref.loc19: %A.type = name_ref T, %T.loc16_15.2 [symbolic = %T.loc16_15.1 (constants.%T.626)]
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.type]
// CHECK:STDOUT: %T.as_type.loc19: type = facet_access_type %T.ref.loc19 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %.loc19: type = converted %T.ref.loc19, %T.as_type.loc19 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %RequiresA.observe.decl.loc19 = observe_decl @RequiresA.observe.loc19 [concrete]
// CHECK:STDOUT: %T.ref.loc20: %A.type = name_ref T, %T.loc16_15.2 [symbolic = %T.loc16_15.1 (constants.%T.626)]
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C.type]
// CHECK:STDOUT: %T.as_type.loc20: type = facet_access_type %T.ref.loc20 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %.loc20: type = converted %T.ref.loc20, %T.as_type.loc20 [symbolic = %T.as_type.loc16_23.1 (constants.%T.as_type.3b8)]
// CHECK:STDOUT: %RequiresA.observe.decl.loc20 = observe_decl @RequiresA.observe.loc20 [concrete]
// CHECK:STDOUT: %RequiresD.ref: %RequiresD.type = name_ref RequiresD, file.%RequiresD.decl [concrete = constants.%RequiresD]
// CHECK:STDOUT: %x.ref.loc21: @RequiresA.%T.as_type.loc16_23.1 (%T.as_type.3b8) = name_ref x, %x
// CHECK:STDOUT: %D.facet.loc21_14.1: %D.type = facet_value constants.%T.as_type.3b8, (constants.%D.lookup_impl_witness) [symbolic = %D.facet.loc21_14.3 (constants.%D.facet.5cf)]
// CHECK:STDOUT: %.loc21_14.1: %D.type = converted constants.%T.as_type.3b8, %D.facet.loc21_14.1 [symbolic = %D.facet.loc21_14.3 (constants.%D.facet.5cf)]
// CHECK:STDOUT: %D.facet.loc21_14.2: %D.type = facet_value constants.%T.as_type.3b8, (constants.%D.lookup_impl_witness) [symbolic = %D.facet.loc21_14.3 (constants.%D.facet.5cf)]
// CHECK:STDOUT: %.loc21_14.2: %D.type = converted constants.%T.as_type.3b8, %D.facet.loc21_14.2 [symbolic = %D.facet.loc21_14.3 (constants.%D.facet.5cf)]
// CHECK:STDOUT: %RequiresD.specific_fn.loc21_3.1: <specific function> = specific_function %RequiresD.ref, @RequiresD(constants.%D.facet.5cf) [symbolic = %RequiresD.specific_fn.loc21_3.2 (constants.%RequiresD.specific_fn)]
// CHECK:STDOUT: %RequiresD.call: init %empty_tuple.type = call %RequiresD.specific_fn.loc21_3.1(%x.ref.loc21)
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: @RequiresA.observe.loc19 {
// CHECK:STDOUT: observe constants.%T.626 impls constants.%B.type
// CHECK:STDOUT: }
// CHECK:STDOUT: @RequiresA.observe.loc20 {
// CHECK:STDOUT: observe constants.%T.626 impls constants.%C.type
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @RequiresA(constants.%T.626) {
// CHECK:STDOUT: %T.patt.loc16_15.2 => constants.%T.patt.a4b
// CHECK:STDOUT: %T.loc16_15.1 => constants.%T.626
// CHECK:STDOUT: %T.as_type.loc16_23.1 => constants.%T.as_type.3b8
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.a0e
// CHECK:STDOUT: %x.param_patt.loc16_21.2 => constants.%x.param_patt.241
// CHECK:STDOUT: %x.patt.loc16_21.2 => constants.%x.patt.cd4828.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_nested_functions_in_outer.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete]
// CHECK:STDOUT: %C.type: type = facet_type <@C> [concrete]
// CHECK:STDOUT: %.Self.frozen.e58: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.029: type = pattern_type %A.type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T: %A.type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic]
// CHECK:STDOUT: %pattern_type.a0e: type = pattern_type %T.as_type [symbolic]
// CHECK:STDOUT: %x.param_patt.241: %pattern_type.a0e = value_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.cd4: %pattern_type.a0e = wrapper_binding_pattern x, %x.param_patt.241 [symbolic]
// CHECK:STDOUT: %TakesA.type: type = fn_type @TakesA [concrete]
// CHECK:STDOUT: %TakesA: %TakesA.type = struct_value () [concrete]
// CHECK:STDOUT: %require_complete.94f: <witness> = require_complete_type %T.as_type [symbolic]
// CHECK:STDOUT: %.Self.frozen.f7e: %B.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %.Self.263: %B.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %B_where.type: type = facet_type <@B where TODO> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type %B_where.type [concrete]
// CHECK:STDOUT: %U.patt: %pattern_type.831 = symbolic_binding_pattern U, 1 [symbolic]
// CHECK:STDOUT: %U: %B_where.type = symbolic_binding U, 1 [symbolic]
// CHECK:STDOUT: %.Self.frozen.8d7: %C.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %.Self.a25: %C.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %C_where.type: type = facet_type <@C where TODO> [concrete]
// CHECK:STDOUT: %pattern_type.803: type = pattern_type %C_where.type [concrete]
// CHECK:STDOUT: %V.patt: %pattern_type.803 = symbolic_binding_pattern V, 2 [symbolic]
// CHECK:STDOUT: %V: %C_where.type = symbolic_binding V, 2 [symbolic]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %U.as_type: type = facet_access_type %U [symbolic]
// CHECK:STDOUT: %eq.bb6 = observe_equivalent %T, %U [symbolic]
// CHECK:STDOUT: %V.as_type: type = facet_access_type %V [symbolic]
// CHECK:STDOUT: %eq.51c = observe_equivalent %U, %V [symbolic]
// CHECK:STDOUT: %pattern_type.0aa: type = pattern_type %V.as_type [symbolic]
// CHECK:STDOUT: %x.param_patt.d48: %pattern_type.0aa = value_param_pattern [symbolic]
// CHECK:STDOUT: %x.patt.860: %pattern_type.0aa = wrapper_binding_pattern x, %x.param_patt.d48 [symbolic]
// CHECK:STDOUT: %InnerF.type: type = fn_type @InnerF, @F(%T, %U, %V) [symbolic]
// CHECK:STDOUT: %InnerF: %InnerF.type = struct_value () [symbolic]
// CHECK:STDOUT: %require_complete.269: <witness> = require_complete_type %V.as_type [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %TakesA.decl: %TakesA.type = fn_decl @TakesA [concrete = constants.%TakesA] {
// CHECK:STDOUT: %T.patt.loc8_12.1: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_12.2 (constants.%T.patt)]
// CHECK:STDOUT: %x.param_patt.loc8_25.1: @TakesA.%pattern_type (%pattern_type.a0e) = value_param_pattern [symbolic = %x.param_patt.loc8_25.2 (constants.%x.param_patt.241)]
// CHECK:STDOUT: %x.patt.loc8_25.1: @TakesA.%pattern_type (%pattern_type.a0e) = wrapper_binding_pattern x, %x.param_patt.loc8_25.1 [symbolic = %x.patt.loc8_25.2 (constants.%x.patt.cd4)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc8_14: type = splice_block %A.ref [concrete = constants.%A.type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.e58]
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc8_12.2: %A.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)]
// CHECK:STDOUT: %x.param: @TakesA.%T.as_type.loc8_27.1 (%T.as_type) = value_param call_param0
// CHECK:STDOUT: %.loc8_27.1: type = splice_block %.loc8_27.2 [symbolic = %T.as_type.loc8_27.1 (constants.%T.as_type)] {
// CHECK:STDOUT: %T.ref: %A.type = name_ref T, %T.loc8_12.2 [symbolic = %T.loc8_12.1 (constants.%T)]
// CHECK:STDOUT: %T.as_type.loc8_27.2: type = facet_access_type %T.ref [symbolic = %T.as_type.loc8_27.1 (constants.%T.as_type)]
// CHECK:STDOUT: %.loc8_27.2: type = converted %T.ref, %T.as_type.loc8_27.2 [symbolic = %T.as_type.loc8_27.1 (constants.%T.as_type)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: @TakesA.%T.as_type.loc8_27.1 (%T.as_type) = wrapper_binding x, %x.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
// CHECK:STDOUT: %T.patt.loc9_7.1: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %U.patt.loc9_13.1: %pattern_type.831 = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc9_13.2 (constants.%U.patt)]
// CHECK:STDOUT: %V.patt.loc9_36.1: %pattern_type.803 = symbolic_binding_pattern V, 2 [symbolic = %V.patt.loc9_36.2 (constants.%V.patt)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc9_9: type = splice_block %A.ref [concrete = constants.%A.type] {
// CHECK:STDOUT: %.Self.frozen.loc9_7: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.e58]
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc9_7.2: %A.type = symbolic_binding T, 0 [symbolic = %T.loc9_7.1 (constants.%T)]
// CHECK:STDOUT: %.loc9_17.1: type = splice_block %.loc9_17.2 [concrete = constants.%B_where.type] {
// CHECK:STDOUT: %.Self.frozen.loc9_13: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.e58]
// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B.type]
// CHECK:STDOUT: %.Self.frozen.loc9_17: %B.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.f7e]
// CHECK:STDOUT: %base_facet_type.loc9_17 = requirement_base_facet_type %B.ref [concrete]
// CHECK:STDOUT: %.Self.ref.loc9_23.1: %B.type = name_ref .Self, %.Self.frozen.loc9_17 [symbolic_self = constants.%.Self.frozen.f7e]
// CHECK:STDOUT: %T.ref.loc9: %A.type = name_ref T, %T.loc9_7.2 [symbolic = constants.%T]
// CHECK:STDOUT: %equiv.loc9_29.1 = requirement_equivalent %.Self.ref.loc9_23.1, %T.ref.loc9 [concrete]
// CHECK:STDOUT: %.Self.loc9_17: %B.type = symbolic_binding .Self [symbolic_self = constants.%.Self.263]
// CHECK:STDOUT: %.Self.ref.loc9_23.2: %B.type = name_ref .Self, %.Self.loc9_17 [symbolic_self = constants.%.Self.263]
// CHECK:STDOUT: %equiv.loc9_29.2 = requirement_equivalent %.Self.ref.loc9_23.2, %T.ref.loc9 [concrete]
// CHECK:STDOUT: %.loc9_17.2: type = where_expr [concrete = constants.%B_where.type] {
// CHECK:STDOUT: %base_facet_type.loc9_17 = requirement_base_facet_type %B.ref [concrete]
// CHECK:STDOUT: %equiv.loc9_29.2 = requirement_equivalent %.Self.ref.loc9_23.2, %T.ref.loc9 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %U.loc9_13.2: %B_where.type = symbolic_binding U, 1 [symbolic = %U.loc9_13.1 (constants.%U)]
// CHECK:STDOUT: %.loc9_40.1: type = splice_block %.loc9_40.2 [concrete = constants.%C_where.type] {
// CHECK:STDOUT: %.Self.frozen.loc9_36: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.e58]
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C.type]
// CHECK:STDOUT: %.Self.frozen.loc9_40: %C.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.8d7]
// CHECK:STDOUT: %base_facet_type.loc9_40 = requirement_base_facet_type %C.ref [concrete]
// CHECK:STDOUT: %.Self.ref.loc9_46.1: %C.type = name_ref .Self, %.Self.frozen.loc9_40 [symbolic_self = constants.%.Self.frozen.8d7]
// CHECK:STDOUT: %U.ref.loc9: %B_where.type = name_ref U, %U.loc9_13.2 [symbolic = constants.%U]
// CHECK:STDOUT: %equiv.loc9_52.1 = requirement_equivalent %.Self.ref.loc9_46.1, %U.ref.loc9 [concrete]
// CHECK:STDOUT: %.Self.loc9_40: %C.type = symbolic_binding .Self [symbolic_self = constants.%.Self.a25]
// CHECK:STDOUT: %.Self.ref.loc9_46.2: %C.type = name_ref .Self, %.Self.loc9_40 [symbolic_self = constants.%.Self.a25]
// CHECK:STDOUT: %equiv.loc9_52.2 = requirement_equivalent %.Self.ref.loc9_46.2, %U.ref.loc9 [concrete]
// CHECK:STDOUT: %.loc9_40.2: type = where_expr [concrete = constants.%C_where.type] {
// CHECK:STDOUT: %base_facet_type.loc9_40 = requirement_base_facet_type %C.ref [concrete]
// CHECK:STDOUT: %equiv.loc9_52.2 = requirement_equivalent %.Self.ref.loc9_46.2, %U.ref.loc9 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %V.loc9_36.2: %C_where.type = symbolic_binding V, 2 [symbolic = %V.loc9_36.1 (constants.%V)]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @TakesA(%T.loc8_12.2: %A.type) {
// CHECK:STDOUT: %T.patt.loc8_12.2: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_12.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.loc8_12.1: %A.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)]
// CHECK:STDOUT: %T.as_type.loc8_27.1: type = facet_access_type %T.loc8_12.1 [symbolic = %T.as_type.loc8_27.1 (constants.%T.as_type)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %T.as_type.loc8_27.1 [symbolic = %pattern_type (constants.%pattern_type.a0e)]
// CHECK:STDOUT: %x.param_patt.loc8_25.2: @TakesA.%pattern_type (%pattern_type.a0e) = value_param_pattern [symbolic = %x.param_patt.loc8_25.2 (constants.%x.param_patt.241)]
// CHECK:STDOUT: %x.patt.loc8_25.2: @TakesA.%pattern_type (%pattern_type.a0e) = wrapper_binding_pattern x, %x.param_patt.loc8_25.2 [symbolic = %x.patt.loc8_25.2 (constants.%x.patt.cd4)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.as_type.loc8_27.1 [symbolic = %require_complete (constants.%require_complete.94f)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @TakesA.%T.as_type.loc8_27.1 (%T.as_type)) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @F(%T.loc9_7.2: %A.type, %U.loc9_13.2: %B_where.type, %V.loc9_36.2: %C_where.type) {
// CHECK:STDOUT: %T.patt.loc9_7.2: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc9_7.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.loc9_7.1: %A.type = symbolic_binding T, 0 [symbolic = %T.loc9_7.1 (constants.%T)]
// CHECK:STDOUT: %U.patt.loc9_13.2: %pattern_type.831 = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc9_13.2 (constants.%U.patt)]
// CHECK:STDOUT: %U.loc9_13.1: %B_where.type = symbolic_binding U, 1 [symbolic = %U.loc9_13.1 (constants.%U)]
// CHECK:STDOUT: %V.patt.loc9_36.2: %pattern_type.803 = symbolic_binding_pattern V, 2 [symbolic = %V.patt.loc9_36.2 (constants.%V.patt)]
// CHECK:STDOUT: %V.loc9_36.1: %C_where.type = symbolic_binding V, 2 [symbolic = %V.loc9_36.1 (constants.%V)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %U.as_type.loc10_16.3: type = facet_access_type %U.loc9_13.1 [symbolic = %U.as_type.loc10_16.3 (constants.%U.as_type)]
// CHECK:STDOUT: %T.as_type.loc10_11.2: type = facet_access_type %T.loc9_7.1 [symbolic = %T.as_type.loc10_11.2 (constants.%T.as_type)]
// CHECK:STDOUT: %eq.loc10_13 = observe_equivalent %T.loc9_7.1, %U.loc9_13.1 [symbolic = %eq.loc10_13 (constants.%eq.bb6)]
// CHECK:STDOUT: %V.as_type.loc10_21.2: type = facet_access_type %V.loc9_36.1 [symbolic = %V.as_type.loc10_21.2 (constants.%V.as_type)]
// CHECK:STDOUT: %eq.loc10_18 = observe_equivalent %U.loc9_13.1, %V.loc9_36.1 [symbolic = %eq.loc10_18 (constants.%eq.51c)]
// CHECK:STDOUT: %InnerF.type: type = fn_type @InnerF, @F(%T.loc9_7.1, %U.loc9_13.1, %V.loc9_36.1) [symbolic = %InnerF.type (constants.%InnerF.type)]
// CHECK:STDOUT: %InnerF: @F.%InnerF.type (%InnerF.type) = struct_value () [symbolic = %InnerF (constants.%InnerF)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %T.ref.loc10: %A.type = name_ref T, %T.loc9_7.2 [symbolic = %T.loc9_7.1 (constants.%T)]
// CHECK:STDOUT: %U.ref.loc10: %B_where.type = name_ref U, %U.loc9_13.2 [symbolic = %U.loc9_13.1 (constants.%U)]
// CHECK:STDOUT: %U.as_type.loc10_16.1: type = facet_access_type %U.ref.loc10 [symbolic = %U.as_type.loc10_16.3 (constants.%U.as_type)]
// CHECK:STDOUT: %.loc10_16.1: type = converted %U.ref.loc10, %U.as_type.loc10_16.1 [symbolic = %U.as_type.loc10_16.3 (constants.%U.as_type)]
// CHECK:STDOUT: %T.as_type.loc10_11.1: type = facet_access_type %T.ref.loc10 [symbolic = %T.as_type.loc10_11.2 (constants.%T.as_type)]
// CHECK:STDOUT: %.loc10_11: type = converted %T.ref.loc10, %T.as_type.loc10_11.1 [symbolic = %T.as_type.loc10_11.2 (constants.%T.as_type)]
// CHECK:STDOUT: %V.ref: %C_where.type = name_ref V, %V.loc9_36.2 [symbolic = %V.loc9_36.1 (constants.%V)]
// CHECK:STDOUT: %V.as_type.loc10_21.1: type = facet_access_type %V.ref [symbolic = %V.as_type.loc10_21.2 (constants.%V.as_type)]
// CHECK:STDOUT: %.loc10_21: type = converted %V.ref, %V.as_type.loc10_21.1 [symbolic = %V.as_type.loc10_21.2 (constants.%V.as_type)]
// CHECK:STDOUT: %U.as_type.loc10_16.2: type = facet_access_type %U.ref.loc10 [symbolic = %U.as_type.loc10_16.3 (constants.%U.as_type)]
// CHECK:STDOUT: %.loc10_16.2: type = converted %U.ref.loc10, %U.as_type.loc10_16.2 [symbolic = %U.as_type.loc10_16.3 (constants.%U.as_type)]
// CHECK:STDOUT: %F.observe.decl = observe_decl @F.observe [concrete]
// CHECK:STDOUT: %InnerF.decl: @F.%InnerF.type (%InnerF.type) = fn_decl @InnerF [symbolic = @F.%InnerF (constants.%InnerF)] {
// CHECK:STDOUT: %x.param_patt.loc12_14.1: @InnerF.%pattern_type (%pattern_type.0aa) = value_param_pattern [symbolic = %x.param_patt.loc12_14.2 (constants.%x.param_patt.d48)]
// CHECK:STDOUT: %x.patt.loc12_14.1: @InnerF.%pattern_type (%pattern_type.0aa) = wrapper_binding_pattern x, %x.param_patt.loc12_14.1 [symbolic = %x.patt.loc12_14.2 (constants.%x.patt.860)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %x.param: @InnerF.%V.as_type.loc12_16.1 (%V.as_type) = value_param call_param0
// CHECK:STDOUT: %.loc12_16.1: type = splice_block %.loc12_16.3 [symbolic = %V.as_type.loc12_16.1 (constants.%V.as_type)] {
// CHECK:STDOUT: %.loc12_16.2: %C_where.type = specific_constant @F.%V.loc9_36.2, @F(constants.%T, constants.%U, constants.%V) [symbolic = %V (constants.%V)]
// CHECK:STDOUT: %V.ref: %C_where.type = name_ref V, %.loc12_16.2 [symbolic = %V (constants.%V)]
// CHECK:STDOUT: %V.as_type.loc12_16.2: type = facet_access_type %V.ref [symbolic = %V.as_type.loc12_16.1 (constants.%V.as_type)]
// CHECK:STDOUT: %.loc12_16.3: type = converted %V.ref, %V.as_type.loc12_16.2 [symbolic = %V.as_type.loc12_16.1 (constants.%V.as_type)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: @InnerF.%V.as_type.loc12_16.1 (%V.as_type) = wrapper_binding x, %x.param
// CHECK:STDOUT: }
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: @F.observe {
// CHECK:STDOUT: observe constants.%T == constants.%U == constants.%V
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @InnerF(@F.%T.loc9_7.2: %A.type, @F.%U.loc9_13.2: %B_where.type, @F.%V.loc9_36.2: %C_where.type) {
// CHECK:STDOUT: %V: %C_where.type = symbolic_binding V, 2 [symbolic = %V (constants.%V)]
// CHECK:STDOUT: %V.as_type.loc12_16.1: type = facet_access_type %V [symbolic = %V.as_type.loc12_16.1 (constants.%V.as_type)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %V.as_type.loc12_16.1 [symbolic = %pattern_type (constants.%pattern_type.0aa)]
// CHECK:STDOUT: %x.param_patt.loc12_14.2: @InnerF.%pattern_type (%pattern_type.0aa) = value_param_pattern [symbolic = %x.param_patt.loc12_14.2 (constants.%x.param_patt.d48)]
// CHECK:STDOUT: %x.patt.loc12_14.2: @InnerF.%pattern_type (%pattern_type.0aa) = wrapper_binding_pattern x, %x.param_patt.loc12_14.2 [symbolic = %x.patt.loc12_14.2 (constants.%x.patt.860)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %V.as_type.loc12_16.1 [symbolic = %require_complete (constants.%require_complete.269)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @InnerF.%V.as_type.loc12_16.1 (%V.as_type)) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %TakesA.ref: %TakesA.type = name_ref TakesA, file.%TakesA.decl [concrete = constants.%TakesA]
// CHECK:STDOUT: %x.ref: @InnerF.%V.as_type.loc12_16.1 (%V.as_type) = name_ref x, %x
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @TakesA(constants.%T) {
// CHECK:STDOUT: %T.patt.loc8_12.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc8_12.1 => constants.%T
// CHECK:STDOUT: %T.as_type.loc8_27.1 => constants.%T.as_type
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.a0e
// CHECK:STDOUT: %x.param_patt.loc8_25.2 => constants.%x.param_patt.241
// CHECK:STDOUT: %x.patt.loc8_25.2 => constants.%x.patt.cd4
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @F(constants.%T, constants.%U, constants.%V) {
// CHECK:STDOUT: %T.patt.loc9_7.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc9_7.1 => constants.%T
// CHECK:STDOUT: %U.patt.loc9_13.2 => constants.%U.patt
// CHECK:STDOUT: %U.loc9_13.1 => constants.%U
// CHECK:STDOUT: %V.patt.loc9_36.2 => constants.%V.patt
// CHECK:STDOUT: %V.loc9_36.1 => constants.%V
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @InnerF(constants.%T, constants.%U, constants.%V) {
// CHECK:STDOUT: %V => constants.%V
// CHECK:STDOUT: %V.as_type.loc12_16.1 => constants.%V.as_type
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.0aa
// CHECK:STDOUT: %x.param_patt.loc12_14.2 => constants.%x.param_patt.d48
// CHECK:STDOUT: %x.patt.loc12_14.2 => constants.%x.patt.860
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- generic_observe.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
// CHECK:STDOUT: %.Self.frozen.e58: type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %pattern_type.029: type = pattern_type %A.type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T: %A.type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %I.type.335: type = generic_interface_type @I [concrete]
// CHECK:STDOUT: %I.generic: %I.type.335 = struct_value () [concrete]
// CHECK:STDOUT: %I.type.414: type = facet_type <@I, @I(%T)> [symbolic]
// CHECK:STDOUT: %Self.c6a: %I.type.414 = symbolic_binding Self, 1 [symbolic]
// CHECK:STDOUT: %facet_type.dee: type = facet_type <@B & @Destroy where TODO> [concrete]
// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I, @I(%T) [symbolic]
// CHECK:STDOUT: %assoc0.9cc: %I.assoc_type = assoc_entity element0, @I.WithSelf.%U [symbolic]
// CHECK:STDOUT: %I.lookup_impl_witness: <witness> = lookup_impl_witness %Self.c6a, @I, @I(%T) [symbolic]
// CHECK:STDOUT: %impl.elem0: %facet_type.dee = impl_witness_access %I.lookup_impl_witness, element0 [symbolic]
// CHECK:STDOUT: %facet_type.93f: type = facet_type <@C & @Destroy where TODO> [concrete]
// CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, @I.WithSelf.%V [symbolic]
// CHECK:STDOUT: %Self.as_type.a01: type = facet_access_type %Self.c6a [symbolic]
// CHECK:STDOUT: %pattern_type.4f3: type = pattern_type %Self.as_type.a01 [symbolic]
// CHECK:STDOUT: %self.param_patt.dbe: %pattern_type.4f3 = value_param_pattern [symbolic]
// CHECK:STDOUT: %self.patt.e5a: %pattern_type.4f3 = wrapper_binding_pattern self, %self.param_patt.dbe [symbolic]
// CHECK:STDOUT: %impl.elem1: %facet_type.93f = impl_witness_access %I.lookup_impl_witness, element1 [symbolic]
// CHECK:STDOUT: %as_type.05f: type = facet_access_type %impl.elem1 [symbolic]
// CHECK:STDOUT: %.e19: Core.Form = init_form %as_type.05f [symbolic]
// CHECK:STDOUT: %pattern_type.c84: type = pattern_type %as_type.05f [symbolic]
// CHECK:STDOUT: %return.param_patt.3e7: %pattern_type.c84 = out_param_pattern [symbolic]
// CHECK:STDOUT: %return.patt.140: %pattern_type.c84 = return_slot_pattern %return.param_patt.3e7, %as_type.05f [symbolic]
// CHECK:STDOUT: %I.WithSelf.GetV.type: type = fn_type @I.WithSelf.GetV, @I.WithSelf(%T, %Self.c6a) [symbolic]
// CHECK:STDOUT: %I.WithSelf.GetV: %I.WithSelf.GetV.type = struct_value () [symbolic]
// CHECK:STDOUT: %assoc2: %I.assoc_type = assoc_entity element2, @I.WithSelf.%I.WithSelf.GetV.decl [symbolic]
// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic]
// CHECK:STDOUT: %pattern_type.a0e: type = pattern_type %T.as_type [symbolic]
// CHECK:STDOUT: %t.param_patt: %pattern_type.a0e = value_param_pattern [symbolic]
// CHECK:STDOUT: %t.patt: %pattern_type.a0e = wrapper_binding_pattern t, %t.param_patt [symbolic]
// CHECK:STDOUT: %I.WithSelf.TakesT.type: type = fn_type @I.WithSelf.TakesT, @I.WithSelf(%T, %Self.c6a) [symbolic]
// CHECK:STDOUT: %I.WithSelf.TakesT: %I.WithSelf.TakesT.type = struct_value () [symbolic]
// CHECK:STDOUT: %assoc3: %I.assoc_type = assoc_entity element3, @I.WithSelf.%I.WithSelf.TakesT.decl [symbolic]
// CHECK:STDOUT: %as_type.a64: type = facet_access_type %impl.elem0 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %I.decl: %I.type.335 = interface_decl @I [concrete = constants.%I.generic] {
// CHECK:STDOUT: %T.patt.loc7_14.1: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_14.2 (constants.%T.patt)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc7: type = splice_block %A.ref [concrete = constants.%A.type] {
// CHECK:STDOUT: %.Self.frozen: type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen.e58]
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %T.loc7_14.2: %A.type = symbolic_binding T, 0 [symbolic = %T.loc7_14.1 (constants.%T)]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic interface @I(%T.loc7_14.2: %A.type) {
// CHECK:STDOUT: %T.patt.loc7_14.2: %pattern_type.029 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_14.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.loc7_14.1: %A.type = symbolic_binding T, 0 [symbolic = %T.loc7_14.1 (constants.%T)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc7_14.1)> [symbolic = %I.type (constants.%I.type.414)]
// CHECK:STDOUT: %Self.loc7_19.2: @I.%I.type (%I.type.414) = symbolic_binding Self, 1 [symbolic = %Self.loc7_19.2 (constants.%Self.c6a)]
// CHECK:STDOUT:
// CHECK:STDOUT: interface {
// CHECK:STDOUT: %Self.loc7_19.1: @I.%I.type (%I.type.414) = symbolic_binding Self, 1 [symbolic = %Self.loc7_19.2 (constants.%Self.c6a)]
// CHECK:STDOUT: %I.WithSelf.decl = interface_with_self_decl @I [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !with Self:
// CHECK:STDOUT: %U: %facet_type.dee = assoc_const_decl @U [concrete] {
// CHECK:STDOUT: %assoc0: @I.WithSelf.%I.assoc_type (%I.assoc_type) = assoc_entity element0, @I.WithSelf.%U [symbolic = @I.WithSelf.%assoc0 (constants.%assoc0.9cc)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %V: %facet_type.93f = assoc_const_decl @V [concrete] {
// CHECK:STDOUT: %assoc1: @I.WithSelf.%I.assoc_type (%I.assoc_type) = assoc_entity element1, @I.WithSelf.%V [symbolic = @I.WithSelf.%assoc1 (constants.%assoc1)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %I.WithSelf.GetV.decl: @I.WithSelf.%I.WithSelf.GetV.type (%I.WithSelf.GetV.type) = fn_decl @I.WithSelf.GetV [symbolic = @I.WithSelf.%I.WithSelf.GetV (constants.%I.WithSelf.GetV)] {
// CHECK:STDOUT: %self.param_patt.loc11_11.1: @I.WithSelf.GetV.%pattern_type.loc11_11 (%pattern_type.4f3) = value_param_pattern [symbolic = %self.param_patt.loc11_11.2 (constants.%self.param_patt.dbe)]
// CHECK:STDOUT: %self.patt.loc11_11.1: @I.WithSelf.GetV.%pattern_type.loc11_11 (%pattern_type.4f3) = wrapper_binding_pattern self, %self.param_patt.loc11_11.1 [symbolic = %self.patt.loc11_11.2 (constants.%self.patt.e5a)]
// CHECK:STDOUT: %return.param_patt.loc11_20.1: @I.WithSelf.GetV.%pattern_type.loc11_20 (%pattern_type.c84) = out_param_pattern [symbolic = %return.param_patt.loc11_20.2 (constants.%return.param_patt.3e7)]
// CHECK:STDOUT: %return.patt.loc11_17.1: @I.WithSelf.GetV.%pattern_type.loc11_20 (%pattern_type.c84) = return_slot_pattern %return.param_patt.loc11_20.1, %.loc11_20.2 [symbolic = %return.patt.loc11_17.2 (constants.%return.patt.140)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %impl.elem1.loc11_20.2: %facet_type.93f = impl_witness_access constants.%I.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc11_20.1 (constants.%impl.elem1)]
// CHECK:STDOUT: %V.ref: %facet_type.93f = name_ref V, %impl.elem1.loc11_20.2 [symbolic = %impl.elem1.loc11_20.1 (constants.%impl.elem1)]
// CHECK:STDOUT: %V.as_type: type = facet_access_type %V.ref [symbolic = %as_type (constants.%as_type.05f)]
// CHECK:STDOUT: %.loc11_20.2: type = converted %V.ref, %V.as_type [symbolic = %as_type (constants.%as_type.05f)]
// CHECK:STDOUT: %.loc11_20.3: Core.Form = init_form %.loc11_20.2 [symbolic = %.loc11_20.1 (constants.%.e19)]
// CHECK:STDOUT: %self.param: @I.WithSelf.GetV.%Self.as_type.loc11_11.1 (%Self.as_type.a01) = value_param call_param0
// CHECK:STDOUT: %.loc11_11.1: type = splice_block %.loc11_11.3 [symbolic = %Self.as_type.loc11_11.1 (constants.%Self.as_type.a01)] {
// CHECK:STDOUT: %.loc11_11.2: @I.WithSelf.GetV.%I.type (%I.type.414) = specific_constant @I.%Self.loc7_19.1, @I(constants.%T) [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.ref: @I.WithSelf.GetV.%I.type (%I.type.414) = name_ref Self, %.loc11_11.2 [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.as_type.loc11_11.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc11_11.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: %.loc11_11.3: type = converted %Self.ref, %Self.as_type.loc11_11.2 [symbolic = %Self.as_type.loc11_11.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %self: @I.WithSelf.GetV.%Self.as_type.loc11_11.1 (%Self.as_type.a01) = wrapper_binding self, %self.param
// CHECK:STDOUT: %return.param: ref @I.WithSelf.GetV.%as_type (%as_type.05f) = out_param call_param1
// CHECK:STDOUT: %return: ref @I.WithSelf.GetV.%as_type (%as_type.05f) = return_slot %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %assoc2.loc11_21.1: @I.WithSelf.%I.assoc_type (%I.assoc_type) = assoc_entity element2, %I.WithSelf.GetV.decl [symbolic = %assoc2.loc11_21.2 (constants.%assoc2)]
// CHECK:STDOUT: %I.WithSelf.TakesT.decl: @I.WithSelf.%I.WithSelf.TakesT.type (%I.WithSelf.TakesT.type) = fn_decl @I.WithSelf.TakesT [symbolic = @I.WithSelf.%I.WithSelf.TakesT (constants.%I.WithSelf.TakesT)] {
// CHECK:STDOUT: %self.param_patt.loc12_13.1: @I.WithSelf.TakesT.%pattern_type.loc12_13 (%pattern_type.4f3) = value_param_pattern [symbolic = %self.param_patt.loc12_13.2 (constants.%self.param_patt.dbe)]
// CHECK:STDOUT: %self.patt.loc12_13.1: @I.WithSelf.TakesT.%pattern_type.loc12_13 (%pattern_type.4f3) = wrapper_binding_pattern self, %self.param_patt.loc12_13.1 [symbolic = %self.patt.loc12_13.2 (constants.%self.patt.e5a)]
// CHECK:STDOUT: %t.param_patt.loc12_20.1: @I.WithSelf.TakesT.%pattern_type.loc12_20 (%pattern_type.a0e) = value_param_pattern [symbolic = %t.param_patt.loc12_20.2 (constants.%t.param_patt)]
// CHECK:STDOUT: %t.patt.loc12_20.1: @I.WithSelf.TakesT.%pattern_type.loc12_20 (%pattern_type.a0e) = wrapper_binding_pattern t, %t.param_patt.loc12_20.1 [symbolic = %t.patt.loc12_20.2 (constants.%t.patt)]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: @I.WithSelf.TakesT.%Self.as_type.loc12_13.1 (%Self.as_type.a01) = value_param call_param0
// CHECK:STDOUT: %.loc12_13.1: type = splice_block %.loc12_13.3 [symbolic = %Self.as_type.loc12_13.1 (constants.%Self.as_type.a01)] {
// CHECK:STDOUT: %.loc12_13.2: @I.WithSelf.TakesT.%I.type (%I.type.414) = specific_constant @I.%Self.loc7_19.1, @I(constants.%T) [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.ref: @I.WithSelf.TakesT.%I.type (%I.type.414) = name_ref Self, %.loc12_13.2 [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.as_type.loc12_13.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc12_13.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: %.loc12_13.3: type = converted %Self.ref, %Self.as_type.loc12_13.2 [symbolic = %Self.as_type.loc12_13.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %self: @I.WithSelf.TakesT.%Self.as_type.loc12_13.1 (%Self.as_type.a01) = wrapper_binding self, %self.param
// CHECK:STDOUT: %t.param: @I.WithSelf.TakesT.%T.as_type.loc12_22.1 (%T.as_type) = value_param call_param1
// CHECK:STDOUT: %.loc12_22.1: type = splice_block %.loc12_22.3 [symbolic = %T.as_type.loc12_22.1 (constants.%T.as_type)] {
// CHECK:STDOUT: %.loc12_22.2: %A.type = specific_constant @I.%T.loc7_14.2, @I(constants.%T) [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %T.ref: %A.type = name_ref T, %.loc12_22.2 [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %T.as_type.loc12_22.2: type = facet_access_type %T.ref [symbolic = %T.as_type.loc12_22.1 (constants.%T.as_type)]
// CHECK:STDOUT: %.loc12_22.3: type = converted %T.ref, %T.as_type.loc12_22.2 [symbolic = %T.as_type.loc12_22.1 (constants.%T.as_type)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %t: @I.WithSelf.TakesT.%T.as_type.loc12_22.1 (%T.as_type) = wrapper_binding t, %t.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %assoc3.loc12_24.1: @I.WithSelf.%I.assoc_type (%I.assoc_type) = assoc_entity element3, %I.WithSelf.TakesT.decl [symbolic = %assoc3.loc12_24.2 (constants.%assoc3)]
// CHECK:STDOUT: %.loc14_11.1: %A.type = specific_constant @I.%T.loc7_14.2, @I(constants.%T) [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %T.ref: %A.type = name_ref T, %.loc14_11.1 [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %impl.elem0.loc14_16.1: %facet_type.dee = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_16.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %U.ref: %facet_type.dee = name_ref U, %impl.elem0.loc14_16.1 [symbolic = %impl.elem0.loc14_16.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %U.as_type.loc14_16.1: type = facet_access_type %U.ref [symbolic = %as_type.loc14_16 (constants.%as_type.a64)]
// CHECK:STDOUT: %.loc14_16.1: type = converted %U.ref, %U.as_type.loc14_16.1 [symbolic = %as_type.loc14_16 (constants.%as_type.a64)]
// CHECK:STDOUT: %T.as_type.loc14_11.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc14_11.2 (constants.%T.as_type)]
// CHECK:STDOUT: %.loc14_11.2: type = converted %T.ref, %T.as_type.loc14_11.1 [symbolic = %T.as_type.loc14_11.2 (constants.%T.as_type)]
// CHECK:STDOUT: %impl.elem1.loc14_21.1: %facet_type.93f = impl_witness_access constants.%I.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc14_21.2 (constants.%impl.elem1)]
// CHECK:STDOUT: %V.ref: %facet_type.93f = name_ref V, %impl.elem1.loc14_21.1 [symbolic = %impl.elem1.loc14_21.2 (constants.%impl.elem1)]
// CHECK:STDOUT: %V.as_type: type = facet_access_type %V.ref [symbolic = %as_type.loc14_21 (constants.%as_type.05f)]
// CHECK:STDOUT: %.loc14_21: type = converted %V.ref, %V.as_type [symbolic = %as_type.loc14_21 (constants.%as_type.05f)]
// CHECK:STDOUT: %U.as_type.loc14_16.2: type = facet_access_type %U.ref [symbolic = %as_type.loc14_16 (constants.%as_type.a64)]
// CHECK:STDOUT: %.loc14_16.2: type = converted %U.ref, %U.as_type.loc14_16.2 [symbolic = %as_type.loc14_16 (constants.%as_type.a64)]
// CHECK:STDOUT: %I.observe.decl = observe_decl @I.observe [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self.loc7_19.1
// CHECK:STDOUT: .B = <poisoned>
// CHECK:STDOUT: .T = <poisoned>
// CHECK:STDOUT: .C = <poisoned>
// CHECK:STDOUT: .B = <poisoned>
// CHECK:STDOUT: .T = <poisoned>
// CHECK:STDOUT: .U = @U.%assoc0
// CHECK:STDOUT: .C = <poisoned>
// CHECK:STDOUT: .V = @V.%assoc1
// CHECK:STDOUT: .GetV = @I.WithSelf.%assoc2.loc11_21.1
// CHECK:STDOUT: .TakesT = @I.WithSelf.%assoc3.loc12_24.1
// CHECK:STDOUT: witness = (@I.WithSelf.%U, @I.WithSelf.%V, @I.WithSelf.%I.WithSelf.GetV.decl, @I.WithSelf.%I.WithSelf.TakesT.decl)
// CHECK:STDOUT:
// CHECK:STDOUT: !requires:
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: @I.observe {
// CHECK:STDOUT: observe constants.%T == constants.%impl.elem0 == constants.%impl.elem1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @I.WithSelf.GetV(@I.%T.loc7_14.2: %A.type, @I.%Self.loc7_19.1: @I.%I.type (%I.type.414)) {
// CHECK:STDOUT: %T: %A.type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.414)]
// CHECK:STDOUT: %Self: @I.WithSelf.GetV.%I.type (%I.type.414) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.as_type.loc11_11.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc11_11.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: %pattern_type.loc11_11: type = pattern_type %Self.as_type.loc11_11.1 [symbolic = %pattern_type.loc11_11 (constants.%pattern_type.4f3)]
// CHECK:STDOUT: %self.param_patt.loc11_11.2: @I.WithSelf.GetV.%pattern_type.loc11_11 (%pattern_type.4f3) = value_param_pattern [symbolic = %self.param_patt.loc11_11.2 (constants.%self.param_patt.dbe)]
// CHECK:STDOUT: %self.patt.loc11_11.2: @I.WithSelf.GetV.%pattern_type.loc11_11 (%pattern_type.4f3) = wrapper_binding_pattern self, %self.param_patt.loc11_11.2 [symbolic = %self.patt.loc11_11.2 (constants.%self.patt.e5a)]
// CHECK:STDOUT: %I.lookup_impl_witness: <witness> = lookup_impl_witness %Self, @I, @I(%T) [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness)]
// CHECK:STDOUT: %impl.elem1.loc11_20.1: %facet_type.93f = impl_witness_access %I.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc11_20.1 (constants.%impl.elem1)]
// CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem1.loc11_20.1 [symbolic = %as_type (constants.%as_type.05f)]
// CHECK:STDOUT: %.loc11_20.1: Core.Form = init_form %as_type [symbolic = %.loc11_20.1 (constants.%.e19)]
// CHECK:STDOUT: %pattern_type.loc11_20: type = pattern_type %as_type [symbolic = %pattern_type.loc11_20 (constants.%pattern_type.c84)]
// CHECK:STDOUT: %return.param_patt.loc11_20.2: @I.WithSelf.GetV.%pattern_type.loc11_20 (%pattern_type.c84) = out_param_pattern [symbolic = %return.param_patt.loc11_20.2 (constants.%return.param_patt.3e7)]
// CHECK:STDOUT: %return.patt.loc11_17.2: @I.WithSelf.GetV.%pattern_type.loc11_20 (%pattern_type.c84) = return_slot_pattern %return.param_patt.loc11_20.2, %as_type [symbolic = %return.patt.loc11_17.2 (constants.%return.patt.140)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%self.param: @I.WithSelf.GetV.%Self.as_type.loc11_11.1 (%Self.as_type.a01)) -> out %return.param: @I.WithSelf.GetV.%as_type (%as_type.05f);
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @I.WithSelf.TakesT(@I.%T.loc7_14.2: %A.type, @I.%Self.loc7_19.1: @I.%I.type (%I.type.414)) {
// CHECK:STDOUT: %T: %A.type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.414)]
// CHECK:STDOUT: %Self: @I.WithSelf.TakesT.%I.type (%I.type.414) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.c6a)]
// CHECK:STDOUT: %Self.as_type.loc12_13.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc12_13.1 (constants.%Self.as_type.a01)]
// CHECK:STDOUT: %pattern_type.loc12_13: type = pattern_type %Self.as_type.loc12_13.1 [symbolic = %pattern_type.loc12_13 (constants.%pattern_type.4f3)]
// CHECK:STDOUT: %self.param_patt.loc12_13.2: @I.WithSelf.TakesT.%pattern_type.loc12_13 (%pattern_type.4f3) = value_param_pattern [symbolic = %self.param_patt.loc12_13.2 (constants.%self.param_patt.dbe)]
// CHECK:STDOUT: %self.patt.loc12_13.2: @I.WithSelf.TakesT.%pattern_type.loc12_13 (%pattern_type.4f3) = wrapper_binding_pattern self, %self.param_patt.loc12_13.2 [symbolic = %self.patt.loc12_13.2 (constants.%self.patt.e5a)]
// CHECK:STDOUT: %T.as_type.loc12_22.1: type = facet_access_type %T [symbolic = %T.as_type.loc12_22.1 (constants.%T.as_type)]
// CHECK:STDOUT: %pattern_type.loc12_20: type = pattern_type %T.as_type.loc12_22.1 [symbolic = %pattern_type.loc12_20 (constants.%pattern_type.a0e)]
// CHECK:STDOUT: %t.param_patt.loc12_20.2: @I.WithSelf.TakesT.%pattern_type.loc12_20 (%pattern_type.a0e) = value_param_pattern [symbolic = %t.param_patt.loc12_20.2 (constants.%t.param_patt)]
// CHECK:STDOUT: %t.patt.loc12_20.2: @I.WithSelf.TakesT.%pattern_type.loc12_20 (%pattern_type.a0e) = wrapper_binding_pattern t, %t.param_patt.loc12_20.2 [symbolic = %t.patt.loc12_20.2 (constants.%t.patt)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%self.param: @I.WithSelf.TakesT.%Self.as_type.loc12_13.1 (%Self.as_type.a01), %t.param: @I.WithSelf.TakesT.%T.as_type.loc12_22.1 (%T.as_type));
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I(constants.%T) {
// CHECK:STDOUT: %T.patt.loc7_14.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc7_14.1 => constants.%T
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf(constants.%T, constants.%Self.c6a) {}
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf.GetV(constants.%T, constants.%Self.c6a) {
// CHECK:STDOUT: %T => constants.%T
// CHECK:STDOUT: %I.type => constants.%I.type.414
// CHECK:STDOUT: %Self => constants.%Self.c6a
// CHECK:STDOUT: %Self.as_type.loc11_11.1 => constants.%Self.as_type.a01
// CHECK:STDOUT: %pattern_type.loc11_11 => constants.%pattern_type.4f3
// CHECK:STDOUT: %self.param_patt.loc11_11.2 => constants.%self.param_patt.dbe
// CHECK:STDOUT: %self.patt.loc11_11.2 => constants.%self.patt.e5a
// CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.lookup_impl_witness
// CHECK:STDOUT: %impl.elem1.loc11_20.1 => constants.%impl.elem1
// CHECK:STDOUT: %as_type => constants.%as_type.05f
// CHECK:STDOUT: %.loc11_20.1 => constants.%.e19
// CHECK:STDOUT: %pattern_type.loc11_20 => constants.%pattern_type.c84
// CHECK:STDOUT: %return.param_patt.loc11_20.2 => constants.%return.param_patt.3e7
// CHECK:STDOUT: %return.patt.loc11_17.2 => constants.%return.patt.140
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf.TakesT(constants.%T, constants.%Self.c6a) {
// CHECK:STDOUT: %T => constants.%T
// CHECK:STDOUT: %I.type => constants.%I.type.414
// CHECK:STDOUT: %Self => constants.%Self.c6a
// CHECK:STDOUT: %Self.as_type.loc12_13.1 => constants.%Self.as_type.a01
// CHECK:STDOUT: %pattern_type.loc12_13 => constants.%pattern_type.4f3
// CHECK:STDOUT: %self.param_patt.loc12_13.2 => constants.%self.param_patt.dbe
// CHECK:STDOUT: %self.patt.loc12_13.2 => constants.%self.patt.e5a
// CHECK:STDOUT: %T.as_type.loc12_22.1 => constants.%T.as_type
// CHECK:STDOUT: %pattern_type.loc12_20 => constants.%pattern_type.a0e
// CHECK:STDOUT: %t.param_patt.loc12_20.2 => constants.%t.param_patt
// CHECK:STDOUT: %t.patt.loc12_20.2 => constants.%t.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: