Reverse nesting of BoundMethod and SpecificFunction. (#5079)

During SemIR, when identifying a specific in a specific context, we'd
have to either look through a specific or through a bound method.
Canonicalize which one to look through first, by having the BoundMethod
created around a SpecificFunction instead.
This changes a lot of check tests.

TODO: As the SemIr does not currently allow removal (access to insts()
is intentionally const), the bound instruction created prior to finding
the specific is not removed from the instructions.
Options: (1) leave as is, (2) add a way to remove the previous bound,
(3) rethink how/when the BoundMethod inst is created.
This commit is contained in:
Alina Sbirlea
2025-03-08 01:34:06 +00:00
committed by GitHub
parent 820ace95e8
commit 7fd54eded0
165 changed files with 2795 additions and 1958 deletions
+6 -4
View File
@@ -34,7 +34,8 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -90,9 +91,10 @@ fn Main() {
// CHECK:STDOUT: %Echo.ref: %Echo.type = name_ref Echo, file.%Echo.decl [concrete = constants.%Echo]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc16_21.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc16_21.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %bound_method.loc16_21.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc16_21.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc16_21.2: %i32 = converted %int_1, %.loc16_21.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %Echo.call: init %i32 = call %Echo.ref(%.loc16_21.2)
+11 -8
View File
@@ -38,13 +38,14 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound.ab5: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.70c: <specific function> = specific_function %Convert.bound.ab5, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.9a1: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.a1c = tuple_value (%int_1.5d2) [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %int_6.462: Core.IntLiteral = int_value 6 [concrete]
// CHECK:STDOUT: %Convert.bound.ce9: <bound method> = bound_method %int_6.462, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.631: <specific function> = specific_function %Convert.bound.ce9, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.efa: <bound method> = bound_method %int_6.462, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_6.e56: %i32 = int_value 6 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -101,9 +102,10 @@ fn Main() {
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %.loc14_22.1: %tuple.type.985 = tuple_literal (%int_1)
// CHECK:STDOUT: %impl.elem0.loc14: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14: <bound method> = bound_method %int_1, %impl.elem0.loc14 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14: <specific function> = specific_function %bound_method.loc14, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %specific_fn.loc14(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc14_22.1: <bound method> = bound_method %int_1, %impl.elem0.loc14 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14: <specific function> = specific_function %impl.elem0.loc14, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_22.2: <bound method> = bound_method %int_1, %specific_fn.loc14 [concrete = constants.%bound_method.9a1]
// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %bound_method.loc14_22.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_22.2: init %i32 = converted %int_1, %int.convert_checked.loc14 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_22.3: init %tuple.type.a1c = tuple_init (%.loc14_22.2) to %x.var [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc14_3.2: init %tuple.type.a1c = converted %.loc14_22.1, %.loc14_22.3 [concrete = constants.%tuple]
@@ -122,9 +124,10 @@ fn Main() {
// CHECK:STDOUT: %int_6: Core.IntLiteral = int_value 6 [concrete = constants.%int_6.462]
// CHECK:STDOUT: %.loc16_8: %i32 = bind_value %tuple.elem0
// CHECK:STDOUT: %impl.elem0.loc16: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc16: <bound method> = bound_method %int_6, %impl.elem0.loc16 [concrete = constants.%Convert.bound.ce9]
// CHECK:STDOUT: %specific_fn.loc16: <specific function> = specific_function %bound_method.loc16, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.631]
// CHECK:STDOUT: %int.convert_checked.loc16: init %i32 = call %specific_fn.loc16(%int_6) [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %bound_method.loc16_12.1: <bound method> = bound_method %int_6, %impl.elem0.loc16 [concrete = constants.%Convert.bound.ce9]
// CHECK:STDOUT: %specific_fn.loc16: <specific function> = specific_function %impl.elem0.loc16, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc16_12.2: <bound method> = bound_method %int_6, %specific_fn.loc16 [concrete = constants.%bound_method.efa]
// CHECK:STDOUT: %int.convert_checked.loc16: init %i32 = call %bound_method.loc16_12.2(%int_6) [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %.loc16_12.1: %i32 = value_of_initializer %int.convert_checked.loc16 [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %.loc16_12.2: %i32 = converted %int_6, %.loc16_12.1 [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %Foo.call: init %empty_tuple.type = call %Foo.ref(%.loc16_8, %.loc16_12.2)
+6 -4
View File
@@ -33,7 +33,8 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -77,9 +78,10 @@ fn Main() {
// CHECK:STDOUT: %Foo.ref: %Foo.type = name_ref Foo, file.%Foo.decl [concrete = constants.%Foo]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc14_7.1: <bound method> = bound_method %int_1, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_7.2: <bound method> = bound_method %int_1, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %bound_method.loc14_7.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.2: %i32 = converted %int_1, %.loc14_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %Foo.call: init %empty_tuple.type = call %Foo.ref(%.loc14_7.2)
@@ -34,7 +34,8 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -78,18 +79,20 @@ fn Main() {
// CHECK:STDOUT: %Foo.ref.loc14: %Foo.type = name_ref Foo, file.%Foo.decl [concrete = constants.%Foo]
// CHECK:STDOUT: %int_1.loc14: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0.loc14: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14: <bound method> = bound_method %int_1.loc14, %impl.elem0.loc14 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc14: <specific function> = specific_function %bound_method.loc14, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %specific_fn.loc14(%int_1.loc14) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc14_7.1: <bound method> = bound_method %int_1.loc14, %impl.elem0.loc14 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc14: <specific function> = specific_function %impl.elem0.loc14, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_7.2: <bound method> = bound_method %int_1.loc14, %specific_fn.loc14 [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked.loc14: init %i32 = call %bound_method.loc14_7.2(%int_1.loc14) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.1: %i32 = value_of_initializer %int.convert_checked.loc14 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.2: %i32 = converted %int_1.loc14, %.loc14_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %Foo.call.loc14: init %empty_tuple.type = call %Foo.ref.loc14(%.loc14_7.2)
// CHECK:STDOUT: %Foo.ref.loc15: %Foo.type = name_ref Foo, file.%Foo.decl [concrete = constants.%Foo]
// CHECK:STDOUT: %int_1.loc15: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0.loc15: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc15: <bound method> = bound_method %int_1.loc15, %impl.elem0.loc15 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc15: <specific function> = specific_function %bound_method.loc15, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %specific_fn.loc15(%int_1.loc15) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc15_7.1: <bound method> = bound_method %int_1.loc15, %impl.elem0.loc15 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc15: <specific function> = specific_function %impl.elem0.loc15, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_7.2: <bound method> = bound_method %int_1.loc15, %specific_fn.loc15 [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %bound_method.loc15_7.2(%int_1.loc15) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_7.1: %i32 = value_of_initializer %int.convert_checked.loc15 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_7.2: %i32 = converted %int_1.loc15, %.loc15_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %Foo.call.loc15: init %empty_tuple.type = call %Foo.ref.loc15(%.loc15_7.2)
+11 -8
View File
@@ -34,10 +34,11 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound.ab5: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.70c: <specific function> = specific_function %Convert.bound.ab5, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.9a1: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %Convert.bound.ef9: <bound method> = bound_method %int_2.ecc, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.787: <specific function> = specific_function %Convert.bound.ef9, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.b92: <bound method> = bound_method %int_2.ecc, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -90,15 +91,17 @@ fn Main() {
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc14_7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14_7: <bound method> = bound_method %int_1, %impl.elem0.loc14_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14_7: <specific function> = specific_function %bound_method.loc14_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc14_7: init %i32 = call %specific_fn.loc14_7(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc14_7.1: <bound method> = bound_method %int_1, %impl.elem0.loc14_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14_7: <specific function> = specific_function %impl.elem0.loc14_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_7.2: <bound method> = bound_method %int_1, %specific_fn.loc14_7 [concrete = constants.%bound_method.9a1]
// CHECK:STDOUT: %int.convert_checked.loc14_7: init %i32 = call %bound_method.loc14_7.2(%int_1) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.1: %i32 = value_of_initializer %int.convert_checked.loc14_7 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.2: %i32 = converted %int_1, %.loc14_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc14_10: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14_10: <bound method> = bound_method %int_2, %impl.elem0.loc14_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc14_10: <specific function> = specific_function %bound_method.loc14_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc14_10: init %i32 = call %specific_fn.loc14_10(%int_2) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %bound_method.loc14_10.1: <bound method> = bound_method %int_2, %impl.elem0.loc14_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc14_10: <specific function> = specific_function %impl.elem0.loc14_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_10.2: <bound method> = bound_method %int_2, %specific_fn.loc14_10 [concrete = constants.%bound_method.b92]
// CHECK:STDOUT: %int.convert_checked.loc14_10: init %i32 = call %bound_method.loc14_10.2(%int_2) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc14_10.1: %i32 = value_of_initializer %int.convert_checked.loc14_10 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc14_10.2: %i32 = converted %int_2, %.loc14_10.1 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %Foo.call: init %empty_tuple.type = call %Foo.ref(%.loc14_7.2, %.loc14_10.2)
@@ -35,10 +35,11 @@ fn Main() {
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound.ab5: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.70c: <specific function> = specific_function %Convert.bound.ab5, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.9a1: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %Convert.bound.ef9: <bound method> = bound_method %int_2.ecc, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn.787: <specific function> = specific_function %Convert.bound.ef9, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.b92: <bound method> = bound_method %int_2.ecc, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -91,15 +92,17 @@ fn Main() {
// CHECK:STDOUT: %int_1.loc14: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %int_2.loc14: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc14_7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14_7: <bound method> = bound_method %int_1.loc14, %impl.elem0.loc14_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14_7: <specific function> = specific_function %bound_method.loc14_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc14_7: init %i32 = call %specific_fn.loc14_7(%int_1.loc14) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc14_7.1: <bound method> = bound_method %int_1.loc14, %impl.elem0.loc14_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc14_7: <specific function> = specific_function %impl.elem0.loc14_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_7.2: <bound method> = bound_method %int_1.loc14, %specific_fn.loc14_7 [concrete = constants.%bound_method.9a1]
// CHECK:STDOUT: %int.convert_checked.loc14_7: init %i32 = call %bound_method.loc14_7.2(%int_1.loc14) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.1: %i32 = value_of_initializer %int.convert_checked.loc14_7 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc14_7.2: %i32 = converted %int_1.loc14, %.loc14_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc14_10: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc14_10: <bound method> = bound_method %int_2.loc14, %impl.elem0.loc14_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc14_10: <specific function> = specific_function %bound_method.loc14_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc14_10: init %i32 = call %specific_fn.loc14_10(%int_2.loc14) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %bound_method.loc14_10.1: <bound method> = bound_method %int_2.loc14, %impl.elem0.loc14_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc14_10: <specific function> = specific_function %impl.elem0.loc14_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_10.2: <bound method> = bound_method %int_2.loc14, %specific_fn.loc14_10 [concrete = constants.%bound_method.b92]
// CHECK:STDOUT: %int.convert_checked.loc14_10: init %i32 = call %bound_method.loc14_10.2(%int_2.loc14) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc14_10.1: %i32 = value_of_initializer %int.convert_checked.loc14_10 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc14_10.2: %i32 = converted %int_2.loc14, %.loc14_10.1 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %Foo.call.loc14: init %empty_tuple.type = call %Foo.ref.loc14(%.loc14_7.2, %.loc14_10.2)
@@ -107,15 +110,17 @@ fn Main() {
// CHECK:STDOUT: %int_1.loc15: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %int_2.loc15: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc15_7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc15_7: <bound method> = bound_method %int_1.loc15, %impl.elem0.loc15_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc15_7: <specific function> = specific_function %bound_method.loc15_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc15_7: init %i32 = call %specific_fn.loc15_7(%int_1.loc15) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc15_7.1: <bound method> = bound_method %int_1.loc15, %impl.elem0.loc15_7 [concrete = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc15_7: <specific function> = specific_function %impl.elem0.loc15_7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_7.2: <bound method> = bound_method %int_1.loc15, %specific_fn.loc15_7 [concrete = constants.%bound_method.9a1]
// CHECK:STDOUT: %int.convert_checked.loc15_7: init %i32 = call %bound_method.loc15_7.2(%int_1.loc15) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_7.1: %i32 = value_of_initializer %int.convert_checked.loc15_7 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc15_7.2: %i32 = converted %int_1.loc15, %.loc15_7.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc15_10: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc15_10: <bound method> = bound_method %int_2.loc15, %impl.elem0.loc15_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc15_10: <specific function> = specific_function %bound_method.loc15_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc15_10: init %i32 = call %specific_fn.loc15_10(%int_2.loc15) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %bound_method.loc15_10.1: <bound method> = bound_method %int_2.loc15, %impl.elem0.loc15_10 [concrete = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc15_10: <specific function> = specific_function %impl.elem0.loc15_10, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_10.2: <bound method> = bound_method %int_2.loc15, %specific_fn.loc15_10 [concrete = constants.%bound_method.b92]
// CHECK:STDOUT: %int.convert_checked.loc15_10: init %i32 = call %bound_method.loc15_10.2(%int_2.loc15) [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc15_10.1: %i32 = value_of_initializer %int.convert_checked.loc15_10 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc15_10.2: %i32 = converted %int_2.loc15, %.loc15_10.1 [concrete = constants.%int_2.ef8]
// CHECK:STDOUT: %Foo.call.loc15: init %empty_tuple.type = call %Foo.ref.loc15(%.loc15_7.2, %.loc15_10.2)
@@ -50,7 +50,8 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_0.5c6, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete]
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.3fa, @F(%F.8b3) [symbolic]
// CHECK:STDOUT: }
@@ -148,9 +149,10 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); }
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
// CHECK:STDOUT: %impl.elem0: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %bound_method, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0) [concrete = constants.%int_0.6a9]
// CHECK:STDOUT: %bound_method.loc8_29.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_29.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %bound_method.loc8_29.2(%int_0) [concrete = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc8_29.1: %i32 = value_of_initializer %int.convert_checked [concrete = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc8_29.2: %i32 = converted %int_0, %.loc8_29.1 [concrete = constants.%int_0.6a9]
// CHECK:STDOUT: return %.loc8_29.2