Reimplement destroy as an interface (#5678)

This changes `Destroy` to use an interface for its implementation.

Note that this change includes a lot of test updates. Even when
`Destroy` is a no-op, it still causes code generation as part of
determining that.

Originally I was trying to use ranges to cut down the scope of this, and
to a degree I think they have. But a flipside here is that cases where
no destructors should be generated -- particularly globals -- would be
needed to completely remove destructor calls. Even for ranges, the range
can often include the destructor placement. So I've shifted
frame-of-thought a little: accept a bunch of destructor churn, because
destructors are needed and will be prevalent. The verbosity is a feature
of the design to make desugaring apparent in IR, not a bug.
This commit is contained in:
Jon Ross-Perkins
2025-06-27 21:57:14 +00:00
committed by GitHub
parent bba037738d
commit 0722dab0ef
171 changed files with 11900 additions and 1434 deletions
+137 -6
View File
@@ -172,6 +172,7 @@ var a: array(1, 1);
// CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete]
// CHECK:STDOUT: %tuple.type.734: type = tuple_type (%C, %C, %C) [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete]
// CHECK:STDOUT: %array_type: type = array_type %int_2, %tuple.type.734 [concrete]
@@ -179,9 +180,28 @@ var a: array(1, 1);
// CHECK:STDOUT: %tuple.type.14a: type = tuple_type (%tuple.type.734, %tuple.type.734) [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.1 [concrete]
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.2, @impl(%T) [symbolic]
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.impl_witness.66a: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%tuple.type.734) [concrete]
// CHECK:STDOUT: %Op.type.fe9: type = fn_type @Op.2, @impl(%tuple.type.734) [concrete]
// CHECK:STDOUT: %Op.ae1: %Op.type.fe9 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.829: %Destroy.type = facet_value %tuple.type.734, (%Destroy.impl_witness.66a) [concrete]
// CHECK:STDOUT: %.e31: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.829 [concrete]
// CHECK:STDOUT: %Op.specific_fn.80d: <specific function> = specific_function %Op.ae1, @Op.2(%tuple.type.734) [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.9e1: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.type.280: type = fn_type @Op.2, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.d4f: %Op.type.280 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.d8f: %Destroy.type = facet_value %array_type, (%Destroy.impl_witness.9e1) [concrete]
// CHECK:STDOUT: %.b1e: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.d8f [concrete]
// CHECK:STDOUT: %Op.specific_fn.04c: <specific function> = specific_function %Op.d4f, @Op.2(%array_type) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_23, loaded [symbolic = @impl.%Op (constants.%Op.46f)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
@@ -205,8 +225,8 @@ var a: array(1, 1);
// CHECK:STDOUT: %F.call.loc10_40: init %tuple.type.734 = call %F.ref.loc10_38() to %.loc10_41.3
// CHECK:STDOUT: %.loc10_41.5: %tuple.type.14a = tuple_literal (%F.call.loc10_35, %F.call.loc10_40)
// CHECK:STDOUT: %.loc10_41.6: init %array_type = array_init (%F.call.loc10_35, %F.call.loc10_40) to %v.var
// CHECK:STDOUT: %.loc10_3: init %array_type = converted %.loc10_41.5, %.loc10_41.6
// CHECK:STDOUT: assign %v.var, %.loc10_3
// CHECK:STDOUT: %.loc10_3.1: init %array_type = converted %.loc10_41.5, %.loc10_41.6
// CHECK:STDOUT: assign %v.var, %.loc10_3.1
// CHECK:STDOUT: %.loc10_28: type = splice_block %array_type [concrete = constants.%array_type] {
// CHECK:STDOUT: %C.ref.loc10_17: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %C.ref.loc10_20: type = name_ref C, file.%C.decl [concrete = constants.%C]
@@ -217,6 +237,38 @@ var a: array(1, 1);
// CHECK:STDOUT: %array_type: type = array_type %int_2, %.loc10_24.2 [concrete = constants.%array_type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %v: ref %array_type = bind_name v, %v.var
// CHECK:STDOUT: %impl.elem0.loc10_41.1: %.e31 = impl_witness_access constants.%Destroy.impl_witness.66a, element0 [concrete = constants.%Op.ae1]
// CHECK:STDOUT: %bound_method.loc10_41.1: <bound method> = bound_method %.loc10_41.3, %impl.elem0.loc10_41.1
// CHECK:STDOUT: %specific_fn.loc10_41.1: <specific function> = specific_function %impl.elem0.loc10_41.1, @Op.2(constants.%tuple.type.734) [concrete = constants.%Op.specific_fn.80d]
// CHECK:STDOUT: %bound_method.loc10_41.2: <bound method> = bound_method %.loc10_41.3, %specific_fn.loc10_41.1
// CHECK:STDOUT: %tuple.elem0.loc10_41.1: ref %C = tuple_access %.loc10_41.3, element0
// CHECK:STDOUT: %.loc10_41.7: %C = bind_value %tuple.elem0.loc10_41.1
// CHECK:STDOUT: %tuple.elem1.loc10_41.1: ref %C = tuple_access %.loc10_41.3, element1
// CHECK:STDOUT: %.loc10_41.8: %C = bind_value %tuple.elem1.loc10_41.1
// CHECK:STDOUT: %tuple.elem2.loc10_41.1: ref %C = tuple_access %.loc10_41.3, element2
// CHECK:STDOUT: %.loc10_41.9: %C = bind_value %tuple.elem2.loc10_41.1
// CHECK:STDOUT: %tuple.loc10_41.1: %tuple.type.734 = tuple_value (%.loc10_41.7, %.loc10_41.8, %.loc10_41.9)
// CHECK:STDOUT: %.loc10_41.10: %tuple.type.734 = converted %.loc10_41.3, %tuple.loc10_41.1
// CHECK:STDOUT: %no_op.loc10_41.1: init %empty_tuple.type = call %bound_method.loc10_41.2(%.loc10_41.10)
// CHECK:STDOUT: %impl.elem0.loc10_41.2: %.e31 = impl_witness_access constants.%Destroy.impl_witness.66a, element0 [concrete = constants.%Op.ae1]
// CHECK:STDOUT: %bound_method.loc10_41.3: <bound method> = bound_method %.loc10_41.1, %impl.elem0.loc10_41.2
// CHECK:STDOUT: %specific_fn.loc10_41.2: <specific function> = specific_function %impl.elem0.loc10_41.2, @Op.2(constants.%tuple.type.734) [concrete = constants.%Op.specific_fn.80d]
// CHECK:STDOUT: %bound_method.loc10_41.4: <bound method> = bound_method %.loc10_41.1, %specific_fn.loc10_41.2
// CHECK:STDOUT: %tuple.elem0.loc10_41.2: ref %C = tuple_access %.loc10_41.1, element0
// CHECK:STDOUT: %.loc10_41.11: %C = bind_value %tuple.elem0.loc10_41.2
// CHECK:STDOUT: %tuple.elem1.loc10_41.2: ref %C = tuple_access %.loc10_41.1, element1
// CHECK:STDOUT: %.loc10_41.12: %C = bind_value %tuple.elem1.loc10_41.2
// CHECK:STDOUT: %tuple.elem2.loc10_41.2: ref %C = tuple_access %.loc10_41.1, element2
// CHECK:STDOUT: %.loc10_41.13: %C = bind_value %tuple.elem2.loc10_41.2
// CHECK:STDOUT: %tuple.loc10_41.2: %tuple.type.734 = tuple_value (%.loc10_41.11, %.loc10_41.12, %.loc10_41.13)
// CHECK:STDOUT: %.loc10_41.14: %tuple.type.734 = converted %.loc10_41.1, %tuple.loc10_41.2
// CHECK:STDOUT: %no_op.loc10_41.2: init %empty_tuple.type = call %bound_method.loc10_41.4(%.loc10_41.14)
// CHECK:STDOUT: %impl.elem0.loc10_3: %.b1e = impl_witness_access constants.%Destroy.impl_witness.9e1, element0 [concrete = constants.%Op.d4f]
// CHECK:STDOUT: %bound_method.loc10_3.1: <bound method> = bound_method %v.var, %impl.elem0.loc10_3
// CHECK:STDOUT: %specific_fn.loc10_3: <specific function> = specific_function %impl.elem0.loc10_3, @Op.2(constants.%array_type) [concrete = constants.%Op.specific_fn.04c]
// CHECK:STDOUT: %bound_method.loc10_3.2: <bound method> = bound_method %v.var, %specific_fn.loc10_3
// CHECK:STDOUT: %.loc10_3.2: %array_type = bind_value %v.var
// CHECK:STDOUT: %no_op.loc10_3: init %empty_tuple.type = call %bound_method.loc10_3.2(%.loc10_3.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -229,9 +281,30 @@ var a: array(1, 1);
// CHECK:STDOUT: %pattern_type.035: type = pattern_type %array_type [concrete]
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete]
// CHECK:STDOUT: %pattern_type.8c1: type = pattern_type %tuple.type [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.1 [concrete]
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.2, @impl(%T) [symbolic]
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.impl_witness.5b3: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%tuple.type) [concrete]
// CHECK:STDOUT: %Op.type.073: type = fn_type @Op.2, @impl(%tuple.type) [concrete]
// CHECK:STDOUT: %Op.dce: %Op.type.073 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.d28: %Destroy.type = facet_value %tuple.type, (%Destroy.impl_witness.5b3) [concrete]
// CHECK:STDOUT: %.886: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.d28 [concrete]
// CHECK:STDOUT: %Op.specific_fn.234: <specific function> = specific_function %Op.dce, @Op.2(%tuple.type) [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple) [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.287: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.type.c60: type = fn_type @Op.2, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.f81: %Op.type.c60 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.409: %Destroy.type = facet_value %array_type, (%Destroy.impl_witness.287) [concrete]
// CHECK:STDOUT: %.b3c: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.409 [concrete]
// CHECK:STDOUT: %Op.specific_fn.29c: <specific function> = specific_function %Op.f81, @Op.2(%array_type) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_23, loaded [symbolic = @impl.%Op (constants.%Op.46f)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
@@ -264,6 +337,28 @@ var a: array(1, 1);
// CHECK:STDOUT: %.loc8_21.6: type = converted %.loc8_21.2, constants.%tuple.type [concrete = constants.%tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %tuple.type = bind_name b, %b.var
// CHECK:STDOUT: %impl.elem0.loc8: %.886 = impl_witness_access constants.%Destroy.impl_witness.5b3, element0 [concrete = constants.%Op.dce]
// CHECK:STDOUT: %bound_method.loc8_3.1: <bound method> = bound_method %b.var, %impl.elem0.loc8
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %impl.elem0.loc8, @Op.2(constants.%tuple.type) [concrete = constants.%Op.specific_fn.234]
// CHECK:STDOUT: %bound_method.loc8_3.2: <bound method> = bound_method %b.var, %specific_fn.loc8
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access %b.var, element0
// CHECK:STDOUT: %tuple.loc8_3.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_3.1: %empty_tuple.type = converted %tuple.elem0, %tuple.loc8_3.1 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %tuple.elem1: ref %empty_tuple.type = tuple_access %b.var, element1
// CHECK:STDOUT: %tuple.loc8_3.2: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_3.2: %empty_tuple.type = converted %tuple.elem1, %tuple.loc8_3.2 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %tuple.elem2: ref %empty_tuple.type = tuple_access %b.var, element2
// CHECK:STDOUT: %tuple.loc8_3.3: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_3.3: %empty_tuple.type = converted %tuple.elem2, %tuple.loc8_3.3 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %tuple.loc8_3.4: %tuple.type = tuple_value (%.loc8_3.1, %.loc8_3.2, %.loc8_3.3) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc8_3.4: %tuple.type = converted %b.var, %tuple.loc8_3.4 [concrete = constants.%tuple]
// CHECK:STDOUT: %no_op.loc8: init %empty_tuple.type = call %bound_method.loc8_3.2(%.loc8_3.4)
// CHECK:STDOUT: %impl.elem0.loc7: %.b3c = impl_witness_access constants.%Destroy.impl_witness.287, element0 [concrete = constants.%Op.f81]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %a.var, %impl.elem0.loc7
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Op.2(constants.%array_type) [concrete = constants.%Op.specific_fn.29c]
// CHECK:STDOUT: %bound_method.loc7_3.2: <bound method> = bound_method %a.var, %specific_fn.loc7
// CHECK:STDOUT: %.loc7_3: %array_type = bind_value %a.var
// CHECK:STDOUT: %no_op.loc7: init %empty_tuple.type = call %bound_method.loc7_3.2(%.loc7_3)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -275,14 +370,34 @@ var a: array(1, 1);
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%empty_tuple) [concrete]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %array_type: type = array_type %int_1, %empty_tuple.type [concrete]
// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %array_type [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %array: %array_type = tuple_value (%empty_tuple) [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.1 [concrete]
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.2, @impl(%T) [symbolic]
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.impl_witness.511: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%tuple.type) [concrete]
// CHECK:STDOUT: %Op.type.23e: type = fn_type @Op.2, @impl(%tuple.type) [concrete]
// CHECK:STDOUT: %Op.f19: %Op.type.23e = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.108: %Destroy.type = facet_value %tuple.type, (%Destroy.impl_witness.511) [concrete]
// CHECK:STDOUT: %.2cd: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.108 [concrete]
// CHECK:STDOUT: %Op.specific_fn.d2b: <specific function> = specific_function %Op.f19, @Op.2(%tuple.type) [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.740: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.type.471: type = fn_type @Op.2, @impl(%array_type) [concrete]
// CHECK:STDOUT: %Op.688: %Op.type.471 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.682: %Destroy.type = facet_value %array_type, (%Destroy.impl_witness.740) [concrete]
// CHECK:STDOUT: %.0ab: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.682 [concrete]
// CHECK:STDOUT: %Op.specific_fn.cae: <specific function> = specific_function %Op.688, @Op.2(%array_type) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_23, loaded [symbolic = @impl.%Op (constants.%Op.46f)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Run() {
@@ -296,14 +411,14 @@ var a: array(1, 1);
// CHECK:STDOUT: %F.call: init %tuple.type = call %F.ref()
// CHECK:STDOUT: %.loc8_27.1: ref %tuple.type = temporary_storage
// CHECK:STDOUT: %.loc8_27.2: ref %tuple.type = temporary %.loc8_27.1, %F.call
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access %.loc8_27.2, element0
// CHECK:STDOUT: %tuple.elem0.loc8_27.1: ref %empty_tuple.type = tuple_access %.loc8_27.2, element0
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
// CHECK:STDOUT: %.loc8_27.3: ref %empty_tuple.type = array_index %t.var, %int_0
// CHECK:STDOUT: %.loc8_27.4: init %empty_tuple.type = tuple_init () to %.loc8_27.3 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_27.5: init %empty_tuple.type = converted %tuple.elem0, %.loc8_27.4 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_27.5: init %empty_tuple.type = converted %tuple.elem0.loc8_27.1, %.loc8_27.4 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_27.6: init %array_type = array_init (%.loc8_27.5) to %t.var [concrete = constants.%array]
// CHECK:STDOUT: %.loc8_3: init %array_type = converted %F.call, %.loc8_27.6 [concrete = constants.%array]
// CHECK:STDOUT: assign %t.var, %.loc8_3
// CHECK:STDOUT: %.loc8_3.1: init %array_type = converted %F.call, %.loc8_27.6 [concrete = constants.%array]
// CHECK:STDOUT: assign %t.var, %.loc8_3.1
// CHECK:STDOUT: %.loc8_21: type = splice_block %array_type [concrete = constants.%array_type] {
// CHECK:STDOUT: %.loc8_17.1: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
@@ -311,6 +426,22 @@ var a: array(1, 1);
// CHECK:STDOUT: %array_type: type = array_type %int_1, %.loc8_17.2 [concrete = constants.%array_type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %t: ref %array_type = bind_name t, %t.var
// CHECK:STDOUT: %impl.elem0.loc8_27: %.2cd = impl_witness_access constants.%Destroy.impl_witness.511, element0 [concrete = constants.%Op.f19]
// CHECK:STDOUT: %bound_method.loc8_27.1: <bound method> = bound_method %.loc8_27.1, %impl.elem0.loc8_27
// CHECK:STDOUT: %specific_fn.loc8_27: <specific function> = specific_function %impl.elem0.loc8_27, @Op.2(constants.%tuple.type) [concrete = constants.%Op.specific_fn.d2b]
// CHECK:STDOUT: %bound_method.loc8_27.2: <bound method> = bound_method %.loc8_27.1, %specific_fn.loc8_27
// CHECK:STDOUT: %tuple.elem0.loc8_27.2: ref %empty_tuple.type = tuple_access %.loc8_27.1, element0
// CHECK:STDOUT: %tuple.loc8_27.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_27.7: %empty_tuple.type = converted %tuple.elem0.loc8_27.2, %tuple.loc8_27.1 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %tuple.loc8_27.2: %tuple.type = tuple_value (%.loc8_27.7) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc8_27.8: %tuple.type = converted %.loc8_27.1, %tuple.loc8_27.2 [concrete = constants.%tuple]
// CHECK:STDOUT: %no_op.loc8_27: init %empty_tuple.type = call %bound_method.loc8_27.2(%.loc8_27.8)
// CHECK:STDOUT: %impl.elem0.loc8_3: %.0ab = impl_witness_access constants.%Destroy.impl_witness.740, element0 [concrete = constants.%Op.688]
// CHECK:STDOUT: %bound_method.loc8_3.1: <bound method> = bound_method %t.var, %impl.elem0.loc8_3
// CHECK:STDOUT: %specific_fn.loc8_3: <specific function> = specific_function %impl.elem0.loc8_3, @Op.2(constants.%array_type) [concrete = constants.%Op.specific_fn.cae]
// CHECK:STDOUT: %bound_method.loc8_3.2: <bound method> = bound_method %t.var, %specific_fn.loc8_3
// CHECK:STDOUT: %.loc8_3.2: %array_type = bind_value %t.var
// CHECK:STDOUT: %no_op.loc8_3: init %empty_tuple.type = call %bound_method.loc8_3.2(%.loc8_3.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
+38 -4
View File
@@ -63,17 +63,34 @@ fn H() { G(3); }
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %array_type.281: type = array_type %int_0, %T [symbolic]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.281 [symbolic]
// CHECK:STDOUT: %require_complete.b7f: <witness> = require_complete_type %array_type.281 [symbolic]
// CHECK:STDOUT: %pattern_type.d48: type = pattern_type %array_type.281 [symbolic]
// CHECK:STDOUT: %array.2ed: %array_type.281 = tuple_value () [symbolic]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Op.type.bae: type = fn_type @Op.1 [concrete]
// CHECK:STDOUT: %Op.type.bc9: type = fn_type @Op.2, @impl(%T) [symbolic]
// CHECK:STDOUT: %Op.46f: %Op.type.bc9 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.281, @Destroy [symbolic]
// CHECK:STDOUT: %Destroy.facet.cdc: %Destroy.type = facet_value %array_type.281, (%Destroy.lookup_impl_witness) [symbolic]
// CHECK:STDOUT: %.77e: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.cdc [symbolic]
// CHECK:STDOUT: %impl.elem0: %.77e = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic]
// CHECK:STDOUT: %specific_impl_fn: <specific function> = specific_impl_function %impl.elem0, @Op.1(%Destroy.facet.cdc) [symbolic]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %array_type.6f1: type = array_type %int_0, %C [concrete]
// CHECK:STDOUT: %complete_type.ed6: <witness> = complete_type_witness %array_type.6f1 [concrete]
// CHECK:STDOUT: %pattern_type.9c8: type = pattern_type %array_type.6f1 [concrete]
// CHECK:STDOUT: %array.2e5: %array_type.6f1 = tuple_value () [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.8b8: <witness> = impl_witness imports.%Destroy.impl_witness_table, @impl(%array_type.6f1) [concrete]
// CHECK:STDOUT: %Op.type.a3e: type = fn_type @Op.2, @impl(%array_type.6f1) [concrete]
// CHECK:STDOUT: %Op.dc5: %Op.type.a3e = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.facet.da7: %Destroy.type = facet_value %array_type.6f1, (%Destroy.impl_witness.8b8) [concrete]
// CHECK:STDOUT: %.a21: type = fn_type_with_self_type %Op.type.bae, %Destroy.facet.da7 [concrete]
// CHECK:STDOUT: %Op.specific_fn: <specific function> = specific_function %Op.dc5, @Op.2(%array_type.6f1) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.0b9: @impl.%Op.type (%Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_23, loaded [symbolic = @impl.%Op (constants.%Op.46f)]
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @G(%T.loc4_6.1: type) {
@@ -81,9 +98,14 @@ fn H() { G(3); }
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %array_type.loc7_22.2: type = array_type constants.%int_0, %T.loc4_6.2 [symbolic = %array_type.loc7_22.2 (constants.%array_type.281)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.loc7_22.2 [symbolic = %require_complete (constants.%require_complete)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.loc7_22.2 [symbolic = %require_complete (constants.%require_complete.b7f)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc7_22.2 [symbolic = %pattern_type (constants.%pattern_type.d48)]
// CHECK:STDOUT: %array: @G.%array_type.loc7_22.2 (%array_type.281) = tuple_value () [symbolic = %array (constants.%array.2ed)]
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc7_22.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %array_type.loc7_22.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.cdc)]
// CHECK:STDOUT: %.loc7_3.4: type = fn_type_with_self_type constants.%Op.type.bae, %Destroy.facet [symbolic = %.loc7_3.4 (constants.%.77e)]
// CHECK:STDOUT: %impl.elem0.loc7_3.2: @G.%.loc7_3.4 (%.77e) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2: <specific function> = specific_impl_function %impl.elem0.loc7_3.2, @Op.1(%Destroy.facet) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn() {
// CHECK:STDOUT: !entry:
@@ -94,14 +116,20 @@ fn H() { G(3); }
// CHECK:STDOUT: %arr.var: ref @G.%array_type.loc7_22.2 (%array_type.281) = var %arr.var_patt
// CHECK:STDOUT: %.loc7_27.1: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc7_27.2: init @G.%array_type.loc7_22.2 (%array_type.281) = array_init () to %arr.var [symbolic = %array (constants.%array.2ed)]
// CHECK:STDOUT: %.loc7_3: init @G.%array_type.loc7_22.2 (%array_type.281) = converted %.loc7_27.1, %.loc7_27.2 [symbolic = %array (constants.%array.2ed)]
// CHECK:STDOUT: assign %arr.var, %.loc7_3
// CHECK:STDOUT: %.loc7_3.1: init @G.%array_type.loc7_22.2 (%array_type.281) = converted %.loc7_27.1, %.loc7_27.2 [symbolic = %array (constants.%array.2ed)]
// CHECK:STDOUT: assign %arr.var, %.loc7_3.1
// CHECK:STDOUT: %.loc7_22: type = splice_block %array_type.loc7_22.1 [symbolic = %array_type.loc7_22.2 (constants.%array_type.281)] {
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_6.1 [symbolic = %T.loc4_6.2 (constants.%T)]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0]
// CHECK:STDOUT: %array_type.loc7_22.1: type = array_type %int_0, %T.ref [symbolic = %array_type.loc7_22.2 (constants.%array_type.281)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %arr: ref @G.%array_type.loc7_22.2 (%array_type.281) = bind_name arr, %arr.var
// CHECK:STDOUT: %impl.elem0.loc7_3.1: @G.%.loc7_3.4 (%.77e) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %arr.var, %impl.elem0.loc7_3.1
// CHECK:STDOUT: %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem0.loc7_3.1, @Op.1(constants.%Destroy.facet.cdc) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
// CHECK:STDOUT: %bound_method.loc7_3.2: <bound method> = bound_method %arr.var, %specific_impl_fn.loc7_3.1
// CHECK:STDOUT: %.loc7_3.2: @G.%array_type.loc7_22.2 (%array_type.281) = bind_value %arr.var
// CHECK:STDOUT: %.loc7_3.3: init %empty_tuple.type = call %bound_method.loc7_3.2(%.loc7_3.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -118,6 +146,11 @@ fn H() { G(3); }
// CHECK:STDOUT: %require_complete => constants.%complete_type.ed6
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9c8
// CHECK:STDOUT: %array => constants.%array.2e5
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.impl_witness.8b8
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.da7
// CHECK:STDOUT: %.loc7_3.4 => constants.%.a21
// CHECK:STDOUT: %impl.elem0.loc7_3.2 => constants.%Op.dc5
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2 => constants.%Op.specific_fn
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_init_template_dependent_bound.carbon
@@ -182,6 +215,7 @@ fn H() { G(3); }
// CHECK:STDOUT: assign %arr.var, <error>
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %arr: <error> = bind_name arr, <error> [concrete = <error>]
// CHECK:STDOUT: %impl.elem0: <error> = impl_witness_access <error>, element0 [concrete = <error>]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }