Support accessing associated functions by member access into facets (#4872)

For an expression such as `(Type as Interface).AssocFn()`, track the
`Self` type `Type` in the result of the member access so that it's
available when checking the function call.

This introduces a new kind of type, `ImplFunctionType`, that represents
the type of a function that is expected within an impl, modeled as the
type of the function within the interface plus a value to use as `Self`.
Calls to values of this type behave like calls to the underlying
function except that the `Self` parameter is pre-bound to the self type
from the facet.

In order to support this, fix an issue where the imported list of
generic bindings lost their association with their enclosing generic.
This adds a little complexity to `import_ref`, including a new recursive
cycle that I intend to address in a follow-up PR.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2025-02-04 22:38:38 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent dcfccd3187
commit fcfb1345d5
234 changed files with 4213 additions and 2531 deletions
+31 -28
View File
@@ -26,10 +26,13 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [template]
// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [template]
// CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [template]
// CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [template]
// CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
// CHECK:STDOUT: %impl_witness.d39: <witness> = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [template]
// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [template]
// CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [template]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [template]
// CHECK:STDOUT: %Convert.bound.ab5: <bound method> = bound_method %int_1.5b8, %Convert.956 [template]
// CHECK:STDOUT: %Convert.specific_fn.70c: <specific function> = specific_function %Convert.bound.ab5, @Convert.2(%int_32) [template]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [template]
@@ -146,16 +149,16 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
// CHECK:STDOUT: %i32.loc11_46: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %.loc11_49.1: %tuple.type.24b = tuple_literal (%i32.loc11_41, %i32.loc11_46)
// CHECK:STDOUT: %.loc11_49.2: type = converted %.loc11_49.1, constants.%tuple.type.d07 [template = constants.%tuple.type.d07]
// CHECK:STDOUT: %impl.elem0.loc11_35.1: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc11_35.1: <bound method> = bound_method %int_1.loc11, %impl.elem0.loc11_35.1 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %Convert.specific_fn.loc11_35.1: <specific function> = specific_function %Convert.bound.loc11_35.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc11_35.1: init %i32 = call %Convert.specific_fn.loc11_35.1(%int_1.loc11) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc11_35.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc11_35.1: <bound method> = bound_method %int_1.loc11, %impl.elem0.loc11_35.1 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc11_35.1: <specific function> = specific_function %bound_method.loc11_35.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc11_35.1: init %i32 = call %specific_fn.loc11_35.1(%int_1.loc11) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc11_35.2: %i32 = value_of_initializer %int.convert_checked.loc11_35.1 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc11_35.3: %i32 = converted %int_1.loc11, %.loc11_35.2 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc11_35.2: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc11_35.2: <bound method> = bound_method %int_2.loc11, %impl.elem0.loc11_35.2 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %Convert.specific_fn.loc11_35.2: <specific function> = specific_function %Convert.bound.loc11_35.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc11_35.2: init %i32 = call %Convert.specific_fn.loc11_35.2(%int_2.loc11) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %impl.elem0.loc11_35.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc11_35.2: <bound method> = bound_method %int_2.loc11, %impl.elem0.loc11_35.2 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc11_35.2: <specific function> = specific_function %bound_method.loc11_35.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc11_35.2: init %i32 = call %specific_fn.loc11_35.2(%int_2.loc11) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc11_35.4: %i32 = value_of_initializer %int.convert_checked.loc11_35.2 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc11_35.5: %i32 = converted %int_2.loc11, %.loc11_35.4 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %tuple.loc11: %tuple.type.d07 = tuple_value (%.loc11_35.3, %.loc11_35.5) [template = constants.%tuple.21c]
@@ -180,22 +183,22 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
// CHECK:STDOUT: %int_32.loc13_99: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc13_99: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %struct_type.b.a.c: type = struct_type {.b: %i32, .a: %i32, .c: %i32} [template = constants.%struct_type.b.a.c]
// CHECK:STDOUT: %impl.elem0.loc13_71.1: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc13_71.1: <bound method> = bound_method %int_2.loc13, %impl.elem0.loc13_71.1 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %Convert.specific_fn.loc13_71.1: <specific function> = specific_function %Convert.bound.loc13_71.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc13_71.1: init %i32 = call %Convert.specific_fn.loc13_71.1(%int_2.loc13) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %impl.elem0.loc13_71.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc13_71.1: <bound method> = bound_method %int_2.loc13, %impl.elem0.loc13_71.1 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc13_71.1: <specific function> = specific_function %bound_method.loc13_71.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc13_71.1: init %i32 = call %specific_fn.loc13_71.1(%int_2.loc13) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc13_71.2: %i32 = value_of_initializer %int.convert_checked.loc13_71.1 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc13_71.3: %i32 = converted %int_2.loc13, %.loc13_71.2 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %impl.elem0.loc13_71.2: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc13_71.2: <bound method> = bound_method %int_1.loc13, %impl.elem0.loc13_71.2 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %Convert.specific_fn.loc13_71.2: <specific function> = specific_function %Convert.bound.loc13_71.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc13_71.2: init %i32 = call %Convert.specific_fn.loc13_71.2(%int_1.loc13) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc13_71.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc13_71.2: <bound method> = bound_method %int_1.loc13, %impl.elem0.loc13_71.2 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc13_71.2: <specific function> = specific_function %bound_method.loc13_71.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc13_71.2: init %i32 = call %specific_fn.loc13_71.2(%int_1.loc13) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc13_71.4: %i32 = value_of_initializer %int.convert_checked.loc13_71.2 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc13_71.5: %i32 = converted %int_1.loc13, %.loc13_71.4 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc13_71.3: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc13_71.3: <bound method> = bound_method %int_3.loc13, %impl.elem0.loc13_71.3 [template = constants.%Convert.bound.b30]
// CHECK:STDOUT: %Convert.specific_fn.loc13_71.3: <specific function> = specific_function %Convert.bound.loc13_71.3, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.b42]
// CHECK:STDOUT: %int.convert_checked.loc13_71.3: init %i32 = call %Convert.specific_fn.loc13_71.3(%int_3.loc13) [template = constants.%int_3.822]
// CHECK:STDOUT: %impl.elem0.loc13_71.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc13_71.3: <bound method> = bound_method %int_3.loc13, %impl.elem0.loc13_71.3 [template = constants.%Convert.bound.b30]
// CHECK:STDOUT: %specific_fn.loc13_71.3: <specific function> = specific_function %bound_method.loc13_71.3, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.b42]
// CHECK:STDOUT: %int.convert_checked.loc13_71.3: init %i32 = call %specific_fn.loc13_71.3(%int_3.loc13) [template = constants.%int_3.822]
// CHECK:STDOUT: %.loc13_71.6: %i32 = value_of_initializer %int.convert_checked.loc13_71.3 [template = constants.%int_3.822]
// CHECK:STDOUT: %.loc13_71.7: %i32 = converted %int_3.loc13, %.loc13_71.6 [template = constants.%int_3.822]
// CHECK:STDOUT: %struct.loc13: %struct_type.b.a.c = struct_value (%.loc13_71.3, %.loc13_71.5, %.loc13_71.7) [template = constants.%struct.21d]
@@ -226,10 +229,10 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
// CHECK:STDOUT: %.loc15_54.2: %tuple.type.d46 = converted %.loc15_54.1, %tuple.loc15 [template = constants.%tuple.869]
// CHECK:STDOUT: %tuple.elem2: Core.IntLiteral = tuple_access %.loc15_54.2, element2 [template = constants.%int_1.5b8]
// CHECK:STDOUT: %array_type.loc15: type = array_type %tuple.elem2, %i32 [template = constants.%array_type]
// CHECK:STDOUT: %impl.elem0.loc15: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc15: <bound method> = bound_method %int_0.loc15_30, %impl.elem0.loc15 [template = constants.%Convert.bound.d04]
// CHECK:STDOUT: %Convert.specific_fn.loc15: <specific function> = specific_function %Convert.bound.loc15, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.d62]
// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %Convert.specific_fn.loc15(%int_0.loc15_30) [template = constants.%int_0.6a9]
// CHECK:STDOUT: %impl.elem0.loc15: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc15: <bound method> = bound_method %int_0.loc15_30, %impl.elem0.loc15 [template = constants.%Convert.bound.d04]
// CHECK:STDOUT: %specific_fn.loc15: <specific function> = specific_function %bound_method.loc15, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.d62]
// CHECK:STDOUT: %int.convert_checked.loc15: init %i32 = call %specific_fn.loc15(%int_0.loc15_30) [template = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc15_32.2: init %i32 = converted %int_0.loc15_30, %int.convert_checked.loc15 [template = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc15_1: ref %array_type = splice_block file.%tuple_index.var {}
// CHECK:STDOUT: %int_0.loc15_32: Core.IntLiteral = int_value 0 [template = constants.%int_0.5c6]
@@ -249,10 +252,10 @@ var struct_access: [i32; 1] = (0,) as [i32; {.a = 3, .b = 1}.b];
// CHECK:STDOUT: %.loc17_60.2: %struct_type.a.b = converted %.loc17_60.1, %struct.loc17 [template = constants.%struct.a81]
// CHECK:STDOUT: %.loc17_61: Core.IntLiteral = struct_access %.loc17_60.2, element1 [template = constants.%int_1.5b8]
// CHECK:STDOUT: %array_type.loc17: type = array_type %.loc17_61, %i32 [template = constants.%array_type]
// CHECK:STDOUT: %impl.elem0.loc17: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17: <bound method> = bound_method %int_0.loc17_32, %impl.elem0.loc17 [template = constants.%Convert.bound.d04]
// CHECK:STDOUT: %Convert.specific_fn.loc17: <specific function> = specific_function %Convert.bound.loc17, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.d62]
// CHECK:STDOUT: %int.convert_checked.loc17: init %i32 = call %Convert.specific_fn.loc17(%int_0.loc17_32) [template = constants.%int_0.6a9]
// CHECK:STDOUT: %impl.elem0.loc17: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17: <bound method> = bound_method %int_0.loc17_32, %impl.elem0.loc17 [template = constants.%Convert.bound.d04]
// CHECK:STDOUT: %specific_fn.loc17: <specific function> = specific_function %bound_method.loc17, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.d62]
// CHECK:STDOUT: %int.convert_checked.loc17: init %i32 = call %specific_fn.loc17(%int_0.loc17_32) [template = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc17_34.2: init %i32 = converted %int_0.loc17_32, %int.convert_checked.loc17 [template = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc17_1: ref %array_type = splice_block file.%struct_access.var {}
// CHECK:STDOUT: %int_0.loc17_34: Core.IntLiteral = int_value 0 [template = constants.%int_0.5c6]
+23 -20
View File
@@ -31,10 +31,13 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]];
// CHECK:STDOUT: %tuple.type.d46: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [template]
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [template]
// CHECK:STDOUT: %array_type.f32: type = array_type %int_4, %i32 [template]
// CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [template]
// CHECK:STDOUT: %Convert.type.1b6: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
// CHECK:STDOUT: %impl_witness.d39: <witness> = impl_witness (imports.%Core.import_ref.a5b), @impl.1(%int_32) [template]
// CHECK:STDOUT: %Convert.type.035: type = fn_type @Convert.2, @impl.1(%int_32) [template]
// CHECK:STDOUT: %Convert.956: %Convert.type.035 = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [template]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [template]
// CHECK:STDOUT: %Convert.bound.4e6: <bound method> = bound_method %int_5.64b, %Convert.956 [template]
// CHECK:STDOUT: %Convert.specific_fn.ba9: <specific function> = specific_function %Convert.bound.4e6, @Convert.2(%int_32) [template]
// CHECK:STDOUT: %int_5.0f6: %i32 = int_value 5 [template]
@@ -99,35 +102,35 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]];
// CHECK:STDOUT: %i32.loc17_61: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [template = constants.%int_4]
// CHECK:STDOUT: %array_type: type = array_type %int_4, %i32 [template = constants.%array_type.f32]
// CHECK:STDOUT: %impl.elem0.loc17_55.1: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17_55.1: <bound method> = bound_method %int_5, %impl.elem0.loc17_55.1 [template = constants.%Convert.bound.4e6]
// CHECK:STDOUT: %Convert.specific_fn.loc17_55.1: <specific function> = specific_function %Convert.bound.loc17_55.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.ba9]
// CHECK:STDOUT: %int.convert_checked.loc17_55.1: init %i32 = call %Convert.specific_fn.loc17_55.1(%int_5) [template = constants.%int_5.0f6]
// CHECK:STDOUT: %impl.elem0.loc17_55.1: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17_55.1: <bound method> = bound_method %int_5, %impl.elem0.loc17_55.1 [template = constants.%Convert.bound.4e6]
// CHECK:STDOUT: %specific_fn.loc17_55.1: <specific function> = specific_function %bound_method.loc17_55.1, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.ba9]
// CHECK:STDOUT: %int.convert_checked.loc17_55.1: init %i32 = call %specific_fn.loc17_55.1(%int_5) [template = constants.%int_5.0f6]
// CHECK:STDOUT: %.loc17_55.2: init %i32 = converted %int_5, %int.convert_checked.loc17_55.1 [template = constants.%int_5.0f6]
// CHECK:STDOUT: %.loc17_55.3: ref %array_type.f32 = temporary_storage
// CHECK:STDOUT: %int_0.loc17_55: Core.IntLiteral = int_value 0 [template = constants.%int_0]
// CHECK:STDOUT: %.loc17_55.4: ref %i32 = array_index %.loc17_55.3, %int_0.loc17_55
// CHECK:STDOUT: %.loc17_55.5: init %i32 = initialize_from %.loc17_55.2 to %.loc17_55.4 [template = constants.%int_5.0f6]
// CHECK:STDOUT: %impl.elem0.loc17_55.2: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17_55.2: <bound method> = bound_method %int_7, %impl.elem0.loc17_55.2 [template = constants.%Convert.bound.208]
// CHECK:STDOUT: %Convert.specific_fn.loc17_55.2: <specific function> = specific_function %Convert.bound.loc17_55.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.c12]
// CHECK:STDOUT: %int.convert_checked.loc17_55.2: init %i32 = call %Convert.specific_fn.loc17_55.2(%int_7) [template = constants.%int_7.0b1]
// CHECK:STDOUT: %impl.elem0.loc17_55.2: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17_55.2: <bound method> = bound_method %int_7, %impl.elem0.loc17_55.2 [template = constants.%Convert.bound.208]
// CHECK:STDOUT: %specific_fn.loc17_55.2: <specific function> = specific_function %bound_method.loc17_55.2, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.c12]
// CHECK:STDOUT: %int.convert_checked.loc17_55.2: init %i32 = call %specific_fn.loc17_55.2(%int_7) [template = constants.%int_7.0b1]
// CHECK:STDOUT: %.loc17_55.6: init %i32 = converted %int_7, %int.convert_checked.loc17_55.2 [template = constants.%int_7.0b1]
// CHECK:STDOUT: %int_1.loc17_55: Core.IntLiteral = int_value 1 [template = constants.%int_1.5b8]
// CHECK:STDOUT: %.loc17_55.7: ref %i32 = array_index %.loc17_55.3, %int_1.loc17_55
// CHECK:STDOUT: %.loc17_55.8: init %i32 = initialize_from %.loc17_55.6 to %.loc17_55.7 [template = constants.%int_7.0b1]
// CHECK:STDOUT: %impl.elem0.loc17_55.3: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17_55.3: <bound method> = bound_method %int_1.loc17_51, %impl.elem0.loc17_55.3 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %Convert.specific_fn.loc17_55.3: <specific function> = specific_function %Convert.bound.loc17_55.3, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc17_55.3: init %i32 = call %Convert.specific_fn.loc17_55.3(%int_1.loc17_51) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc17_55.3: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17_55.3: <bound method> = bound_method %int_1.loc17_51, %impl.elem0.loc17_55.3 [template = constants.%Convert.bound.ab5]
// CHECK:STDOUT: %specific_fn.loc17_55.3: <specific function> = specific_function %bound_method.loc17_55.3, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.70c]
// CHECK:STDOUT: %int.convert_checked.loc17_55.3: init %i32 = call %specific_fn.loc17_55.3(%int_1.loc17_51) [template = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc17_55.9: init %i32 = converted %int_1.loc17_51, %int.convert_checked.loc17_55.3 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %int_2.loc17_55: Core.IntLiteral = int_value 2 [template = constants.%int_2.ecc]
// CHECK:STDOUT: %.loc17_55.10: ref %i32 = array_index %.loc17_55.3, %int_2.loc17_55
// CHECK:STDOUT: %.loc17_55.11: init %i32 = initialize_from %.loc17_55.9 to %.loc17_55.10 [template = constants.%int_1.5d2]
// CHECK:STDOUT: %impl.elem0.loc17_55.4: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17_55.4: <bound method> = bound_method %int_9, %impl.elem0.loc17_55.4 [template = constants.%Convert.bound.9e2]
// CHECK:STDOUT: %Convert.specific_fn.loc17_55.4: <specific function> = specific_function %Convert.bound.loc17_55.4, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.b02]
// CHECK:STDOUT: %int.convert_checked.loc17_55.4: init %i32 = call %Convert.specific_fn.loc17_55.4(%int_9) [template = constants.%int_9.f88]
// CHECK:STDOUT: %impl.elem0.loc17_55.4: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17_55.4: <bound method> = bound_method %int_9, %impl.elem0.loc17_55.4 [template = constants.%Convert.bound.9e2]
// CHECK:STDOUT: %specific_fn.loc17_55.4: <specific function> = specific_function %bound_method.loc17_55.4, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.b02]
// CHECK:STDOUT: %int.convert_checked.loc17_55.4: init %i32 = call %specific_fn.loc17_55.4(%int_9) [template = constants.%int_9.f88]
// CHECK:STDOUT: %.loc17_55.12: init %i32 = converted %int_9, %int.convert_checked.loc17_55.4 [template = constants.%int_9.f88]
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [template = constants.%int_3]
// CHECK:STDOUT: %.loc17_55.13: ref %i32 = array_index %.loc17_55.3, %int_3
@@ -138,10 +141,10 @@ var array_index: [i32; 1] = (0,) as [i32; ((5, 7, 1, 9) as [i32; 4])[2]];
// CHECK:STDOUT: %.loc17_57.2: ref %array_type.f32 = temporary %.loc17_55.3, %.loc17_57.1
// CHECK:STDOUT: %int_32.loc17_71: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc17_71: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %impl.elem0.loc17_70: %Convert.type.1b6 = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %Convert.bound.loc17_70: <bound method> = bound_method %int_2.loc17_70, %impl.elem0.loc17_70 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %Convert.specific_fn.loc17_70: <specific function> = specific_function %Convert.bound.loc17_70, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc17_70: init %i32 = call %Convert.specific_fn.loc17_70(%int_2.loc17_70) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %impl.elem0.loc17_70: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [template = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc17_70: <bound method> = bound_method %int_2.loc17_70, %impl.elem0.loc17_70 [template = constants.%Convert.bound.ef9]
// CHECK:STDOUT: %specific_fn.loc17_70: <specific function> = specific_function %bound_method.loc17_70, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn.787]
// CHECK:STDOUT: %int.convert_checked.loc17_70: init %i32 = call %specific_fn.loc17_70(%int_2.loc17_70) [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc17_70.1: %i32 = value_of_initializer %int.convert_checked.loc17_70 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc17_70.2: %i32 = converted %int_2.loc17_70, %.loc17_70.1 [template = constants.%int_2.ef8]
// CHECK:STDOUT: %.loc17_71.1: ref %i32 = array_index %.loc17_57.2, %.loc17_70.2
+10 -7
View File
@@ -42,10 +42,13 @@ fn G(N:! i32) {
// CHECK:STDOUT: %N.patt.8e2: %i32 = symbolic_binding_pattern N, 0 [symbolic]
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.type.2fd: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [template]
// CHECK:STDOUT: %Convert.type.71e: type = fn_type @Convert.1, @ImplicitAs(Core.IntLiteral) [template]
// CHECK:STDOUT: %impl_witness.023: <witness> = impl_witness (imports.%Core.import_ref.85c), @impl.2(%int_32) [template]
// CHECK:STDOUT: %Convert.type.4ad: type = fn_type @Convert.3, @impl.2(%int_32) [template]
// CHECK:STDOUT: %Convert.960: %Convert.type.4ad = struct_value () [template]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2fd = facet_value %i32, %impl_witness.023 [template]
// CHECK:STDOUT: %.10e: type = fn_type_with_self_type %Convert.type.71e, %ImplicitAs.facet [template]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %N.51e, %Convert.960 [symbolic]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.3(%int_32) [symbolic]
// CHECK:STDOUT: %int.convert_checked: init Core.IntLiteral = call %Convert.specific_fn(%N.51e) [symbolic]
@@ -149,9 +152,9 @@ fn G(N:! i32) {
// CHECK:STDOUT: %N.patt.loc18_6.2: %i32 = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc18_6.2 (constants.%N.patt.8e2)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Convert.bound.loc19_16.2: <bound method> = bound_method %N.loc18_6.2, constants.%Convert.960 [symbolic = %Convert.bound.loc19_16.2 (constants.%Convert.bound)]
// CHECK:STDOUT: %Convert.specific_fn.loc19_16.2: <specific function> = specific_function %Convert.bound.loc19_16.2, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn.loc19_16.2 (constants.%Convert.specific_fn)]
// CHECK:STDOUT: %int.convert_checked.loc19_16.2: init Core.IntLiteral = call %Convert.specific_fn.loc19_16.2(%N.loc18_6.2) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %N.loc18_6.2, constants.%Convert.960 [symbolic = %Convert.bound (constants.%Convert.bound)]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)]
// CHECK:STDOUT: %int.convert_checked.loc19_16.2: init Core.IntLiteral = call %Convert.specific_fn(%N.loc18_6.2) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %array_type.loc19_17.2: type = array_type %int.convert_checked.loc19_16.2, %i32 [symbolic = %array_type.loc19_17.2 (constants.%array_type.b04)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type @G.%array_type.loc19_17.2 (%array_type.b04) [symbolic = %require_complete (constants.%require_complete.9dc)]
// CHECK:STDOUT:
@@ -166,10 +169,10 @@ fn G(N:! i32) {
// CHECK:STDOUT: %int_32.loc19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc18_6.1 [symbolic = %N.loc18_6.2 (constants.%N.51e)]
// CHECK:STDOUT: %impl.elem0: %Convert.type.71e = impl_witness_access constants.%impl_witness.023, element0 [template = constants.%Convert.960]
// CHECK:STDOUT: %Convert.bound.loc19_16.1: <bound method> = bound_method %N.ref, %impl.elem0 [symbolic = %Convert.bound.loc19_16.2 (constants.%Convert.bound)]
// CHECK:STDOUT: %Convert.specific_fn.loc19_16.1: <specific function> = specific_function %Convert.bound.loc19_16.1, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn.loc19_16.2 (constants.%Convert.specific_fn)]
// CHECK:STDOUT: %int.convert_checked.loc19_16.1: init Core.IntLiteral = call %Convert.specific_fn.loc19_16.1(%N.ref) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %impl.elem0: %.10e = impl_witness_access constants.%impl_witness.023, element0 [template = constants.%Convert.960]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %N.ref, %impl.elem0 [symbolic = %Convert.bound (constants.%Convert.bound)]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %bound_method, @Convert.3(constants.%int_32) [symbolic = %Convert.specific_fn (constants.%Convert.specific_fn)]
// CHECK:STDOUT: %int.convert_checked.loc19_16.1: init Core.IntLiteral = call %specific_fn(%N.ref) [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %.loc19_16.1: Core.IntLiteral = value_of_initializer %int.convert_checked.loc19_16.1 [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %.loc19_16.2: Core.IntLiteral = converted %N.ref, %.loc19_16.1 [symbolic = %int.convert_checked.loc19_16.2 (constants.%int.convert_checked)]
// CHECK:STDOUT: %array_type.loc19_17.1: type = array_type %.loc19_16.2, %i32 [symbolic = %array_type.loc19_17.2 (constants.%array_type.b04)]