Support for converting a function to a C++ function pointer (#7789)

This commit is contained in:
Geoff Romer
2026-09-30 21:13:36 +00:00
committed by GitHub
parent cbdd6cee65
commit c0bd9606de
26 changed files with 1030 additions and 446 deletions
@@ -31,6 +31,8 @@ fn F() {
Cpp.TakesArray(&n[0]);
Cpp.TakesArray(Cpp.nullptr);
Cpp.TakesFunction(G);
//@dump-sem-ir-end
}
@@ -44,12 +46,6 @@ fn G(n: i32) -> i32;
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE+4]]:21: error: call argument of type `<type of G>` is not supported [CppCallArgTypeNotSupported]
// CHECK:STDERR: Cpp.TakesFunction(G);
// CHECK:STDERR: ^
// CHECK:STDERR:
Cpp.TakesFunction(G);
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE+4]]:21: error: call argument of type `<type of Cpp.Function>` is not supported [CppCallArgTypeNotSupported]
// CHECK:STDERR: Cpp.TakesFunction(Cpp.Function);
// CHECK:STDERR: ^~~~~~~~~~~~
@@ -58,9 +54,9 @@ fn F() {
var n: array(i32, 42);
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE+8]]:26: error: no matching function for call to 'TakesFunction' [CppInteropParseError]
// CHECK:STDERR: 31 | Cpp.TakesFunction(&n[0]);
// CHECK:STDERR: 25 | Cpp.TakesFunction(&n[0]);
// CHECK:STDERR: | ^
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE-22]]:10: in file included here [InCppInclude]
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE-16]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./params.h:3:6: note: candidate function not viable: no known conversion from 'int * _Nonnull' to 'int (*)(int)' for 1st argument [CppInteropParseNote]
// CHECK:STDERR: 3 | void TakesFunction(int f(int));
// CHECK:STDERR: | ^ ~~~~~~~~~~
@@ -73,7 +69,7 @@ fn F() {
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE+8]]:21: note: type `Cpp.nullptr_t` does not implement interface `Core.ImplicitAs(<C++ type int (*)(int)>)` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: Cpp.TakesFunction(Cpp.nullptr);
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE-35]]:10: in file included here [InCppInclude]
// CHECK:STDERR: fail_todo_call_params_2.carbon:[[@LINE-29]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./params.h:3:24: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: void TakesFunction(int f(int));
// CHECK:STDERR: ^
@@ -90,6 +86,8 @@ fn F() {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete]
// CHECK:STDOUT: %array_type.d58: type = array_type %int_42, %i32 [concrete]
// CHECK:STDOUT: %pattern_type.c07: type = pattern_type %array_type.d58 [concrete]
@@ -204,6 +202,12 @@ fn F() {
// CHECK:STDOUT: %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %uninit, %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.60f [concrete]
// CHECK:STDOUT: %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.60f, @Cpp.nullptr_t.as.ImplicitAs.impl.Convert(%i32) [concrete]
// CHECK:STDOUT: %bound_method.518: <bound method> = bound_method %uninit, %Cpp.nullptr_t.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %TakesFunction.cpp_overload_set.type: type = cpp_overload_set_type @TakesFunction.cpp_overload_set [concrete]
// CHECK:STDOUT: %TakesFunction.cpp_overload_set.value: %TakesFunction.cpp_overload_set.type = cpp_overload_set_value @TakesFunction.cpp_overload_set [concrete]
// CHECK:STDOUT: %.659: type = cpp_fn_ptr_type clang_function_pointer_type7E000000 [concrete]
// CHECK:STDOUT: %TakesFunction.type: type = fn_type @TakesFunction [concrete]
// CHECK:STDOUT: %TakesFunction: %TakesFunction.type = struct_value () [concrete]
// CHECK:STDOUT: %.266: %.659 = cpp_addr_of_fn %G, @G [concrete]
// CHECK:STDOUT: %self.param_patt.705: %pattern_type.6b6 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.70d: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt.705 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.6: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_3.1 [concrete]
@@ -266,6 +270,7 @@ fn F() {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .TakesArray = %TakesArray.cpp_overload_set.value
// CHECK:STDOUT: .nullptr = @F.%uninit
// CHECK:STDOUT: .TakesFunction = %TakesFunction.cpp_overload_set.value
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import_ref.083: @T.as_type.as.DefaultOrUnformed.impl.52f.%T.as_type.as.DefaultOrUnformed.impl.Op.type (%T.as_type.as.DefaultOrUnformed.impl.Op.type.215) = import_ref Core//prelude/default, loc{{\d+_\d+}}, loaded [symbolic = @T.as_type.as.DefaultOrUnformed.impl.52f.%T.as_type.as.DefaultOrUnformed.impl.Op (constants.%T.as_type.as.DefaultOrUnformed.impl.Op.f65)]
@@ -300,6 +305,12 @@ fn F() {
// CHECK:STDOUT: %OptionalAs.impl_witness_table.2e9 = impl_witness_table (%Core.import_ref.017d8), @T.as_type.as.OptionalAs.impl [concrete]
// CHECK:STDOUT: %Core.import_ref.49d: @Cpp.nullptr_t.as.ImplicitAs.impl.%Cpp.nullptr_t.as.ImplicitAs.impl.Convert.type (%Cpp.nullptr_t.as.ImplicitAs.impl.Convert.type.1b3) = import_ref Core//prelude/types/cpp/nullptr, loc{{\d+_\d+}}, loaded [symbolic = @Cpp.nullptr_t.as.ImplicitAs.impl.%Cpp.nullptr_t.as.ImplicitAs.impl.Convert (constants.%Cpp.nullptr_t.as.ImplicitAs.impl.Convert.208)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.898 = impl_witness_table (%Core.import_ref.49d), @Cpp.nullptr_t.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: %TakesFunction.cpp_overload_set.value: %TakesFunction.cpp_overload_set.type = cpp_overload_set_value @TakesFunction.cpp_overload_set [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %TakesFunction.decl: %TakesFunction.type = fn_decl @TakesFunction [concrete = constants.%TakesFunction] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
@@ -438,6 +449,12 @@ fn F() {
// CHECK:STDOUT: %TakesArray.call.loc13: init %empty_tuple.type = call imports.%TakesArray.decl(%.loc13_21.4)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13: <bound method> = bound_method %.loc13_21.3, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.4
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13(%.loc13_21.3)
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %G.ref: %G.type = name_ref G, file.%G.decl [concrete = constants.%G]
// CHECK:STDOUT: %.loc15_21.1: %.659 = cpp_addr_of_fn %G.ref, @G [concrete = constants.%.266]
// CHECK:STDOUT: %.loc15_21.2: %.659 = converted %G.ref, %.loc15_21.1 [concrete = constants.%.266]
// CHECK:STDOUT: %TakesFunction.call: init %empty_tuple.type = call imports.%TakesFunction.decl(%.loc15_21.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc10: <bound method> = bound_method %n.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.7
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc10: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc10(%n.var)
// CHECK:STDOUT: <elided>
@@ -677,8 +694,6 @@ fn F() {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %TakesFunction.cpp_overload_set.type: type = cpp_overload_set_type @TakesFunction.cpp_overload_set [concrete]
// CHECK:STDOUT: %TakesFunction.cpp_overload_set.value: %TakesFunction.cpp_overload_set.type = cpp_overload_set_value @TakesFunction.cpp_overload_set [concrete]
// CHECK:STDOUT: %Function.cpp_overload_set.type: type = cpp_overload_set_type @Function.cpp_overload_set [concrete]
@@ -722,15 +737,15 @@ fn F() {
// CHECK:STDOUT: %TakesFunction: %TakesFunction.type = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.705: %pattern_type.6b6 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.70d: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt.705 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc22_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc16_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc22_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc16_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc22_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc16_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.087: %pattern_type.c07 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.b22: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt.087 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc22_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc16_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %int_41: Core.IntLiteral = int_value 41 [concrete]
// CHECK:STDOUT: %int_40: Core.IntLiteral = int_value 40 [concrete]
@@ -772,9 +787,9 @@ fn F() {
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc22_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc16_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc22_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc16_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -801,28 +816,28 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc22_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc16_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc22_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc16_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc22_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc16_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c07 = ref_param_pattern [concrete = constants.%self.param_patt.087]
// CHECK:STDOUT: %self.patt: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.b22]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type.d58 = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type.d58 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc22_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc16_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c07 = ref_param_pattern [concrete = constants.%self.param_patt.087]
// CHECK:STDOUT: %self.patt: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.b22]
// CHECK:STDOUT: } {
@@ -833,23 +848,20 @@ fn F() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc14: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Cpp.ref.loc14_3: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc14: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %G.ref: %G.type = name_ref G, file.%G.decl [concrete = constants.%G]
// CHECK:STDOUT: %Cpp.ref.loc20_3: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc20: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc20_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Cpp.ref.loc14_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Function.ref: %Function.cpp_overload_set.type = name_ref Function, imports.%Function.cpp_overload_set.value [concrete = constants.%Function.cpp_overload_set.value]
// CHECK:STDOUT: %n.var: ref %array_type.d58 = var_storage %n.var_patt
// CHECK:STDOUT: %DefaultOrUnformed.facet: %DefaultOrUnformed.type = facet_value constants.%array_type.d58, (constants.%DefaultOrUnformed.impl_witness.06a) [concrete = constants.%DefaultOrUnformed.facet]
// CHECK:STDOUT: %.loc22_24.1: %DefaultOrUnformed.type = converted constants.%array_type.d58, %DefaultOrUnformed.facet [concrete = constants.%DefaultOrUnformed.facet]
// CHECK:STDOUT: %as_type: type = facet_access_type %.loc22_24.1 [concrete = constants.%array_type.d58]
// CHECK:STDOUT: %.loc22_24.2: type = converted %.loc22_24.1, %as_type [concrete = constants.%array_type.d58]
// CHECK:STDOUT: %.loc16_24.1: %DefaultOrUnformed.type = converted constants.%array_type.d58, %DefaultOrUnformed.facet [concrete = constants.%DefaultOrUnformed.facet]
// CHECK:STDOUT: %as_type: type = facet_access_type %.loc16_24.1 [concrete = constants.%array_type.d58]
// CHECK:STDOUT: %.loc16_24.2: type = converted %.loc16_24.1, %as_type [concrete = constants.%array_type.d58]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc22_3: ref %array_type.d58 = splice_block %n.var {}
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.call: init %array_type.d58 to %.loc22_3 = call %T.as_type.as.DefaultOrUnformed.impl.Op.specific_fn()
// CHECK:STDOUT: %.loc16_3: ref %array_type.d58 = splice_block %n.var {}
// CHECK:STDOUT: %T.as_type.as.DefaultOrUnformed.impl.Op.call: init %array_type.d58 to %.loc16_3 = call %T.as_type.as.DefaultOrUnformed.impl.Op.specific_fn()
// CHECK:STDOUT: assign %n.var, %T.as_type.as.DefaultOrUnformed.impl.Op.call
// CHECK:STDOUT: %.loc22_23: type = splice_block %array_type [concrete = constants.%array_type.d58] {
// CHECK:STDOUT: %.loc16_23: type = splice_block %array_type [concrete = constants.%array_type.d58] {
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42]
// CHECK:STDOUT: %array_type: type = array_type %int_42, %i32 [concrete = constants.%array_type.d58]
@@ -859,218 +871,218 @@ fn F() {
// CHECK:STDOUT: %n.patt: %pattern_type.c07 = ref_binding_pattern n [concrete = constants.%n.patt.dac]
// CHECK:STDOUT: %n.var_patt: %pattern_type.c07 = var_pattern %n.patt [concrete = constants.%n.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.ref.loc31: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc31: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc25: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc25: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %n.ref: ref %array_type.d58 = name_ref n, %n
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
// CHECK:STDOUT: %impl.elem0: %.b7a = impl_witness_access constants.%ImplicitAs.impl_witness.a2a, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc31_24.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc25_24.1: <bound method> = bound_method %int_0, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc31_24.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc31_24.2(%int_0) [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc31_24.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc31_24.2: %i32 = converted %int_0, %.loc31_24.1 [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc31_25: ref %i32 = array_index %n.ref, %.loc31_24.2
// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc31_25
// CHECK:STDOUT: %Cpp.ref.loc44_3: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc44: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc44_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %bound_method.loc25_24.2: <bound method> = bound_method %int_0, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc25_24.2(%int_0) [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc25_24.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc25_24.2: %i32 = converted %int_0, %.loc25_24.1 [concrete = constants.%int_0.3c0]
// CHECK:STDOUT: %.loc25_25: ref %i32 = array_index %n.ref, %.loc25_24.2
// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc25_25
// CHECK:STDOUT: %Cpp.ref.loc38_3: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakesFunction.ref.loc38: %TakesFunction.cpp_overload_set.type = name_ref TakesFunction, imports.%TakesFunction.cpp_overload_set.value [concrete = constants.%TakesFunction.cpp_overload_set.value]
// CHECK:STDOUT: %Cpp.ref.loc38_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %nullptr.ref: %Cpp.nullptr_t = name_ref nullptr, %uninit [concrete = constants.%uninit]
// CHECK:STDOUT: %.loc44: %.659 = converted %nullptr.ref, <error> [concrete = <error>]
// CHECK:STDOUT: %.loc38: %.659 = converted %nullptr.ref, <error> [concrete = <error>]
// CHECK:STDOUT: %TakesFunction.call: init %empty_tuple.type = call imports.%TakesFunction.decl(<error>)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %n.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%n.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc22_3.1(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc16_3.1(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc22_3.1(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc16_3.1(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc22_3.1(%self.param: ref %i32) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc16_3.1(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc22_3.2(%self.param: ref %array_type.d58) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc16_3.2(%self.param: ref %array_type.d58) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %int_41: Core.IntLiteral = int_value 41 [concrete = constants.%int_41]
// CHECK:STDOUT: %.loc22_3.1: ref %i32 = array_index %self.param, %int_41
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.1: <bound method> = bound_method %.loc22_3.1, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.1: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.1(%.loc22_3.1)
// CHECK:STDOUT: %.loc16_3.1: ref %i32 = array_index %self.param, %int_41
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.1: <bound method> = bound_method %.loc16_3.1, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.1: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.1(%.loc16_3.1)
// CHECK:STDOUT: %int_40: Core.IntLiteral = int_value 40 [concrete = constants.%int_40]
// CHECK:STDOUT: %.loc22_3.2: ref %i32 = array_index %self.param, %int_40
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.2: <bound method> = bound_method %.loc22_3.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.2: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.2(%.loc22_3.2)
// CHECK:STDOUT: %.loc16_3.2: ref %i32 = array_index %self.param, %int_40
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.2: <bound method> = bound_method %.loc16_3.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.2: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.2(%.loc16_3.2)
// CHECK:STDOUT: %int_39: Core.IntLiteral = int_value 39 [concrete = constants.%int_39]
// CHECK:STDOUT: %.loc22_3.3: ref %i32 = array_index %self.param, %int_39
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.3: <bound method> = bound_method %.loc22_3.3, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.3: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.3(%.loc22_3.3)
// CHECK:STDOUT: %.loc16_3.3: ref %i32 = array_index %self.param, %int_39
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.3: <bound method> = bound_method %.loc16_3.3, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.3: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.3(%.loc16_3.3)
// CHECK:STDOUT: %int_38: Core.IntLiteral = int_value 38 [concrete = constants.%int_38]
// CHECK:STDOUT: %.loc22_3.4: ref %i32 = array_index %self.param, %int_38
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.4: <bound method> = bound_method %.loc22_3.4, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.4: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.4(%.loc22_3.4)
// CHECK:STDOUT: %.loc16_3.4: ref %i32 = array_index %self.param, %int_38
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.4: <bound method> = bound_method %.loc16_3.4, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.4: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.4(%.loc16_3.4)
// CHECK:STDOUT: %int_37: Core.IntLiteral = int_value 37 [concrete = constants.%int_37]
// CHECK:STDOUT: %.loc22_3.5: ref %i32 = array_index %self.param, %int_37
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.5: <bound method> = bound_method %.loc22_3.5, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.5: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.5(%.loc22_3.5)
// CHECK:STDOUT: %.loc16_3.5: ref %i32 = array_index %self.param, %int_37
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.5: <bound method> = bound_method %.loc16_3.5, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.5: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.5(%.loc16_3.5)
// CHECK:STDOUT: %int_36: Core.IntLiteral = int_value 36 [concrete = constants.%int_36]
// CHECK:STDOUT: %.loc22_3.6: ref %i32 = array_index %self.param, %int_36
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.6: <bound method> = bound_method %.loc22_3.6, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.6: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.6(%.loc22_3.6)
// CHECK:STDOUT: %.loc16_3.6: ref %i32 = array_index %self.param, %int_36
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.6: <bound method> = bound_method %.loc16_3.6, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.6: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.6(%.loc16_3.6)
// CHECK:STDOUT: %int_35: Core.IntLiteral = int_value 35 [concrete = constants.%int_35]
// CHECK:STDOUT: %.loc22_3.7: ref %i32 = array_index %self.param, %int_35
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.7: <bound method> = bound_method %.loc22_3.7, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.7: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.7(%.loc22_3.7)
// CHECK:STDOUT: %.loc16_3.7: ref %i32 = array_index %self.param, %int_35
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.7: <bound method> = bound_method %.loc16_3.7, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.7: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.7(%.loc16_3.7)
// CHECK:STDOUT: %int_34: Core.IntLiteral = int_value 34 [concrete = constants.%int_34]
// CHECK:STDOUT: %.loc22_3.8: ref %i32 = array_index %self.param, %int_34
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.8: <bound method> = bound_method %.loc22_3.8, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.8: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.8(%.loc22_3.8)
// CHECK:STDOUT: %.loc16_3.8: ref %i32 = array_index %self.param, %int_34
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.8: <bound method> = bound_method %.loc16_3.8, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.8: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.8(%.loc16_3.8)
// CHECK:STDOUT: %int_33: Core.IntLiteral = int_value 33 [concrete = constants.%int_33]
// CHECK:STDOUT: %.loc22_3.9: ref %i32 = array_index %self.param, %int_33
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.9: <bound method> = bound_method %.loc22_3.9, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.9: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.9(%.loc22_3.9)
// CHECK:STDOUT: %.loc16_3.9: ref %i32 = array_index %self.param, %int_33
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.9: <bound method> = bound_method %.loc16_3.9, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.9: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.9(%.loc16_3.9)
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %.loc22_3.10: ref %i32 = array_index %self.param, %int_32
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.10: <bound method> = bound_method %.loc22_3.10, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.10: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.10(%.loc22_3.10)
// CHECK:STDOUT: %.loc16_3.10: ref %i32 = array_index %self.param, %int_32
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.10: <bound method> = bound_method %.loc16_3.10, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.10: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.10(%.loc16_3.10)
// CHECK:STDOUT: %int_31: Core.IntLiteral = int_value 31 [concrete = constants.%int_31]
// CHECK:STDOUT: %.loc22_3.11: ref %i32 = array_index %self.param, %int_31
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.11: <bound method> = bound_method %.loc22_3.11, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.11: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.11(%.loc22_3.11)
// CHECK:STDOUT: %.loc16_3.11: ref %i32 = array_index %self.param, %int_31
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.11: <bound method> = bound_method %.loc16_3.11, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.11: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.11(%.loc16_3.11)
// CHECK:STDOUT: %int_30: Core.IntLiteral = int_value 30 [concrete = constants.%int_30]
// CHECK:STDOUT: %.loc22_3.12: ref %i32 = array_index %self.param, %int_30
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.12: <bound method> = bound_method %.loc22_3.12, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.12: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.12(%.loc22_3.12)
// CHECK:STDOUT: %.loc16_3.12: ref %i32 = array_index %self.param, %int_30
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.12: <bound method> = bound_method %.loc16_3.12, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.12: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.12(%.loc16_3.12)
// CHECK:STDOUT: %int_29: Core.IntLiteral = int_value 29 [concrete = constants.%int_29]
// CHECK:STDOUT: %.loc22_3.13: ref %i32 = array_index %self.param, %int_29
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.13: <bound method> = bound_method %.loc22_3.13, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.13: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.13(%.loc22_3.13)
// CHECK:STDOUT: %.loc16_3.13: ref %i32 = array_index %self.param, %int_29
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.13: <bound method> = bound_method %.loc16_3.13, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.13: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.13(%.loc16_3.13)
// CHECK:STDOUT: %int_28: Core.IntLiteral = int_value 28 [concrete = constants.%int_28]
// CHECK:STDOUT: %.loc22_3.14: ref %i32 = array_index %self.param, %int_28
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.14: <bound method> = bound_method %.loc22_3.14, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.14: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.14(%.loc22_3.14)
// CHECK:STDOUT: %.loc16_3.14: ref %i32 = array_index %self.param, %int_28
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.14: <bound method> = bound_method %.loc16_3.14, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.14: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.14(%.loc16_3.14)
// CHECK:STDOUT: %int_27: Core.IntLiteral = int_value 27 [concrete = constants.%int_27]
// CHECK:STDOUT: %.loc22_3.15: ref %i32 = array_index %self.param, %int_27
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.15: <bound method> = bound_method %.loc22_3.15, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.15: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.15(%.loc22_3.15)
// CHECK:STDOUT: %.loc16_3.15: ref %i32 = array_index %self.param, %int_27
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.15: <bound method> = bound_method %.loc16_3.15, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.15: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.15(%.loc16_3.15)
// CHECK:STDOUT: %int_26: Core.IntLiteral = int_value 26 [concrete = constants.%int_26]
// CHECK:STDOUT: %.loc22_3.16: ref %i32 = array_index %self.param, %int_26
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.16: <bound method> = bound_method %.loc22_3.16, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.16: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.16(%.loc22_3.16)
// CHECK:STDOUT: %.loc16_3.16: ref %i32 = array_index %self.param, %int_26
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.16: <bound method> = bound_method %.loc16_3.16, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.16: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.16(%.loc16_3.16)
// CHECK:STDOUT: %int_25: Core.IntLiteral = int_value 25 [concrete = constants.%int_25]
// CHECK:STDOUT: %.loc22_3.17: ref %i32 = array_index %self.param, %int_25
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.17: <bound method> = bound_method %.loc22_3.17, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.17: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.17(%.loc22_3.17)
// CHECK:STDOUT: %.loc16_3.17: ref %i32 = array_index %self.param, %int_25
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.17: <bound method> = bound_method %.loc16_3.17, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.17: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.17(%.loc16_3.17)
// CHECK:STDOUT: %int_24: Core.IntLiteral = int_value 24 [concrete = constants.%int_24]
// CHECK:STDOUT: %.loc22_3.18: ref %i32 = array_index %self.param, %int_24
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.18: <bound method> = bound_method %.loc22_3.18, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.18: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.18(%.loc22_3.18)
// CHECK:STDOUT: %.loc16_3.18: ref %i32 = array_index %self.param, %int_24
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.18: <bound method> = bound_method %.loc16_3.18, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.18: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.18(%.loc16_3.18)
// CHECK:STDOUT: %int_23: Core.IntLiteral = int_value 23 [concrete = constants.%int_23]
// CHECK:STDOUT: %.loc22_3.19: ref %i32 = array_index %self.param, %int_23
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.19: <bound method> = bound_method %.loc22_3.19, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.19: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.19(%.loc22_3.19)
// CHECK:STDOUT: %.loc16_3.19: ref %i32 = array_index %self.param, %int_23
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.19: <bound method> = bound_method %.loc16_3.19, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.19: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.19(%.loc16_3.19)
// CHECK:STDOUT: %int_22: Core.IntLiteral = int_value 22 [concrete = constants.%int_22]
// CHECK:STDOUT: %.loc22_3.20: ref %i32 = array_index %self.param, %int_22
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.20: <bound method> = bound_method %.loc22_3.20, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.20: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.20(%.loc22_3.20)
// CHECK:STDOUT: %.loc16_3.20: ref %i32 = array_index %self.param, %int_22
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.20: <bound method> = bound_method %.loc16_3.20, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.20: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.20(%.loc16_3.20)
// CHECK:STDOUT: %int_21: Core.IntLiteral = int_value 21 [concrete = constants.%int_21]
// CHECK:STDOUT: %.loc22_3.21: ref %i32 = array_index %self.param, %int_21
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.21: <bound method> = bound_method %.loc22_3.21, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.21: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.21(%.loc22_3.21)
// CHECK:STDOUT: %.loc16_3.21: ref %i32 = array_index %self.param, %int_21
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.21: <bound method> = bound_method %.loc16_3.21, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.21: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.21(%.loc16_3.21)
// CHECK:STDOUT: %int_20: Core.IntLiteral = int_value 20 [concrete = constants.%int_20]
// CHECK:STDOUT: %.loc22_3.22: ref %i32 = array_index %self.param, %int_20
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.22: <bound method> = bound_method %.loc22_3.22, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.22: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.22(%.loc22_3.22)
// CHECK:STDOUT: %.loc16_3.22: ref %i32 = array_index %self.param, %int_20
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.22: <bound method> = bound_method %.loc16_3.22, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.22: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.22(%.loc16_3.22)
// CHECK:STDOUT: %int_19: Core.IntLiteral = int_value 19 [concrete = constants.%int_19]
// CHECK:STDOUT: %.loc22_3.23: ref %i32 = array_index %self.param, %int_19
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.23: <bound method> = bound_method %.loc22_3.23, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.23: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.23(%.loc22_3.23)
// CHECK:STDOUT: %.loc16_3.23: ref %i32 = array_index %self.param, %int_19
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.23: <bound method> = bound_method %.loc16_3.23, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.23: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.23(%.loc16_3.23)
// CHECK:STDOUT: %int_18: Core.IntLiteral = int_value 18 [concrete = constants.%int_18]
// CHECK:STDOUT: %.loc22_3.24: ref %i32 = array_index %self.param, %int_18
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.24: <bound method> = bound_method %.loc22_3.24, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.24: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.24(%.loc22_3.24)
// CHECK:STDOUT: %.loc16_3.24: ref %i32 = array_index %self.param, %int_18
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.24: <bound method> = bound_method %.loc16_3.24, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.24: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.24(%.loc16_3.24)
// CHECK:STDOUT: %int_17: Core.IntLiteral = int_value 17 [concrete = constants.%int_17]
// CHECK:STDOUT: %.loc22_3.25: ref %i32 = array_index %self.param, %int_17
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.25: <bound method> = bound_method %.loc22_3.25, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.25: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.25(%.loc22_3.25)
// CHECK:STDOUT: %.loc16_3.25: ref %i32 = array_index %self.param, %int_17
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.25: <bound method> = bound_method %.loc16_3.25, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.25: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.25(%.loc16_3.25)
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
// CHECK:STDOUT: %.loc22_3.26: ref %i32 = array_index %self.param, %int_16
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.26: <bound method> = bound_method %.loc22_3.26, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.26: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.26(%.loc22_3.26)
// CHECK:STDOUT: %.loc16_3.26: ref %i32 = array_index %self.param, %int_16
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.26: <bound method> = bound_method %.loc16_3.26, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.26: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.26(%.loc16_3.26)
// CHECK:STDOUT: %int_15: Core.IntLiteral = int_value 15 [concrete = constants.%int_15]
// CHECK:STDOUT: %.loc22_3.27: ref %i32 = array_index %self.param, %int_15
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.27: <bound method> = bound_method %.loc22_3.27, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.27: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.27(%.loc22_3.27)
// CHECK:STDOUT: %.loc16_3.27: ref %i32 = array_index %self.param, %int_15
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.27: <bound method> = bound_method %.loc16_3.27, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.27: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.27(%.loc16_3.27)
// CHECK:STDOUT: %int_14: Core.IntLiteral = int_value 14 [concrete = constants.%int_14]
// CHECK:STDOUT: %.loc22_3.28: ref %i32 = array_index %self.param, %int_14
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.28: <bound method> = bound_method %.loc22_3.28, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.28: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.28(%.loc22_3.28)
// CHECK:STDOUT: %.loc16_3.28: ref %i32 = array_index %self.param, %int_14
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.28: <bound method> = bound_method %.loc16_3.28, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.28: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.28(%.loc16_3.28)
// CHECK:STDOUT: %int_13: Core.IntLiteral = int_value 13 [concrete = constants.%int_13]
// CHECK:STDOUT: %.loc22_3.29: ref %i32 = array_index %self.param, %int_13
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.29: <bound method> = bound_method %.loc22_3.29, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.29: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.29(%.loc22_3.29)
// CHECK:STDOUT: %.loc16_3.29: ref %i32 = array_index %self.param, %int_13
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.29: <bound method> = bound_method %.loc16_3.29, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.29: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.29(%.loc16_3.29)
// CHECK:STDOUT: %int_12: Core.IntLiteral = int_value 12 [concrete = constants.%int_12]
// CHECK:STDOUT: %.loc22_3.30: ref %i32 = array_index %self.param, %int_12
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.30: <bound method> = bound_method %.loc22_3.30, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.30: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.30(%.loc22_3.30)
// CHECK:STDOUT: %.loc16_3.30: ref %i32 = array_index %self.param, %int_12
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.30: <bound method> = bound_method %.loc16_3.30, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.30: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.30(%.loc16_3.30)
// CHECK:STDOUT: %int_11: Core.IntLiteral = int_value 11 [concrete = constants.%int_11]
// CHECK:STDOUT: %.loc22_3.31: ref %i32 = array_index %self.param, %int_11
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.31: <bound method> = bound_method %.loc22_3.31, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.31: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.31(%.loc22_3.31)
// CHECK:STDOUT: %.loc16_3.31: ref %i32 = array_index %self.param, %int_11
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.31: <bound method> = bound_method %.loc16_3.31, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.31: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.31(%.loc16_3.31)
// CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete = constants.%int_10]
// CHECK:STDOUT: %.loc22_3.32: ref %i32 = array_index %self.param, %int_10
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.32: <bound method> = bound_method %.loc22_3.32, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.32: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.32(%.loc22_3.32)
// CHECK:STDOUT: %.loc16_3.32: ref %i32 = array_index %self.param, %int_10
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.32: <bound method> = bound_method %.loc16_3.32, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.32: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.32(%.loc16_3.32)
// CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9]
// CHECK:STDOUT: %.loc22_3.33: ref %i32 = array_index %self.param, %int_9
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.33: <bound method> = bound_method %.loc22_3.33, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.33: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.33(%.loc22_3.33)
// CHECK:STDOUT: %.loc16_3.33: ref %i32 = array_index %self.param, %int_9
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.33: <bound method> = bound_method %.loc16_3.33, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.33: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.33(%.loc16_3.33)
// CHECK:STDOUT: %int_8: Core.IntLiteral = int_value 8 [concrete = constants.%int_8]
// CHECK:STDOUT: %.loc22_3.34: ref %i32 = array_index %self.param, %int_8
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.34: <bound method> = bound_method %.loc22_3.34, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.34: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.34(%.loc22_3.34)
// CHECK:STDOUT: %.loc16_3.34: ref %i32 = array_index %self.param, %int_8
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.34: <bound method> = bound_method %.loc16_3.34, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.34: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.34(%.loc16_3.34)
// CHECK:STDOUT: %int_7: Core.IntLiteral = int_value 7 [concrete = constants.%int_7]
// CHECK:STDOUT: %.loc22_3.35: ref %i32 = array_index %self.param, %int_7
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.35: <bound method> = bound_method %.loc22_3.35, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.35: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.35(%.loc22_3.35)
// CHECK:STDOUT: %.loc16_3.35: ref %i32 = array_index %self.param, %int_7
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.35: <bound method> = bound_method %.loc16_3.35, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.35: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.35(%.loc16_3.35)
// CHECK:STDOUT: %int_6: Core.IntLiteral = int_value 6 [concrete = constants.%int_6]
// CHECK:STDOUT: %.loc22_3.36: ref %i32 = array_index %self.param, %int_6
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.36: <bound method> = bound_method %.loc22_3.36, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.36: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.36(%.loc22_3.36)
// CHECK:STDOUT: %.loc16_3.36: ref %i32 = array_index %self.param, %int_6
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.36: <bound method> = bound_method %.loc16_3.36, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.36: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.36(%.loc16_3.36)
// CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5]
// CHECK:STDOUT: %.loc22_3.37: ref %i32 = array_index %self.param, %int_5
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.37: <bound method> = bound_method %.loc22_3.37, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.37: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.37(%.loc22_3.37)
// CHECK:STDOUT: %.loc16_3.37: ref %i32 = array_index %self.param, %int_5
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.37: <bound method> = bound_method %.loc16_3.37, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.37: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.37(%.loc16_3.37)
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4]
// CHECK:STDOUT: %.loc22_3.38: ref %i32 = array_index %self.param, %int_4
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.38: <bound method> = bound_method %.loc22_3.38, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.38: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.38(%.loc22_3.38)
// CHECK:STDOUT: %.loc16_3.38: ref %i32 = array_index %self.param, %int_4
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.38: <bound method> = bound_method %.loc16_3.38, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.38: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.38(%.loc16_3.38)
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3]
// CHECK:STDOUT: %.loc22_3.39: ref %i32 = array_index %self.param, %int_3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.39: <bound method> = bound_method %.loc22_3.39, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.39: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.39(%.loc22_3.39)
// CHECK:STDOUT: %.loc16_3.39: ref %i32 = array_index %self.param, %int_3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.39: <bound method> = bound_method %.loc16_3.39, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.39: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.39(%.loc16_3.39)
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
// CHECK:STDOUT: %.loc22_3.40: ref %i32 = array_index %self.param, %int_2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.40: <bound method> = bound_method %.loc22_3.40, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.40: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.40(%.loc22_3.40)
// CHECK:STDOUT: %.loc16_3.40: ref %i32 = array_index %self.param, %int_2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.40: <bound method> = bound_method %.loc16_3.40, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.40: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.40(%.loc16_3.40)
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
// CHECK:STDOUT: %.loc22_3.41: ref %i32 = array_index %self.param, %int_1
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.41: <bound method> = bound_method %.loc22_3.41, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.41: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.41(%.loc22_3.41)
// CHECK:STDOUT: %.loc16_3.41: ref %i32 = array_index %self.param, %int_1
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.41: <bound method> = bound_method %.loc16_3.41, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.41: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.41(%.loc16_3.41)
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
// CHECK:STDOUT: %.loc22_3.42: ref %i32 = array_index %self.param, %int_0
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc22_3.42: <bound method> = bound_method %.loc22_3.42, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc22_3.42: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc22_3.42(%.loc22_3.42)
// CHECK:STDOUT: %.loc16_3.42: ref %i32 = array_index %self.param, %int_0
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc16_3.42: <bound method> = bound_method %.loc16_3.42, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc16_3.42: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc16_3.42(%.loc16_3.42)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc22_3.2(%self.param: ref %array_type.d58) = "no_op";
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc16_3.2(%self.param: ref %array_type.d58) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc22_3.2(%self.param: ref %array_type.d58) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc16_3.2(%self.param: ref %array_type.d58) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
@@ -9,6 +9,7 @@
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/function/import/function_ptr.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/function/import/function_ptr.carbon
// CHECK:STDERR: error: calling function with incomplete return type 'C' [CppInteropParseError]
// --- simple_callback.h
@@ -29,7 +30,7 @@ fn F() {
//@dump-sem-ir-end
}
// --- fail_todo_convert_fn_ptr.carbon
// --- convert_fn_ptr.carbon
library "[[@TEST_NAME]]";
import Cpp library "simple_callback.h";
@@ -38,15 +39,11 @@ fn MyCallback(arg: f32) -> i32;
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_convert_fn_ptr.carbon:[[@LINE+4]]:41: error: expression cannot be used as a value [UseOfNonExprAsValue]
// CHECK:STDERR: var unused fn_ptr: Cpp.CallbackType = MyCallback;
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
var unused fn_ptr: Cpp.CallbackType = MyCallback;
//@dump-sem-ir-end
}
// --- fail_todo_pass_fn_ptr.carbon
// --- pass_fn_ptr.carbon
library "[[@TEST_NAME]]";
import Cpp library "simple_callback.h";
@@ -55,10 +52,6 @@ fn MyCallback(arg: f32) -> i32;
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_pass_fn_ptr.carbon:[[@LINE+4]]:20: error: call argument of type `<type of MyCallback>` is not supported [CppCallArgTypeNotSupported]
// CHECK:STDERR: Cpp.TakeCallback(MyCallback);
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
Cpp.TakeCallback(MyCallback);
//@dump-sem-ir-end
}
@@ -95,7 +88,7 @@ fn F() {
//@dump-sem-ir-end
}
// --- fail_todo_convert_complex_fn_ptr.carbon
// --- convert_complex_fn_ptr.carbon
library "[[@TEST_NAME]]";
import Cpp library "complex_callback.h";
@@ -104,15 +97,11 @@ fn MyCallback(arg: Cpp.C) -> Cpp.C;
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_convert_complex_fn_ptr.carbon:[[@LINE+4]]:41: error: expression cannot be used as a value [UseOfNonExprAsValue]
// CHECK:STDERR: var unused fn_ptr: Cpp.CallbackType = MyCallback;
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
var unused fn_ptr: Cpp.CallbackType = MyCallback;
//@dump-sem-ir-end
}
// --- fail_todo_pass_complex_fn_ptr.carbon
// --- pass_complex_fn_ptr.carbon
library "[[@TEST_NAME]]";
import Cpp library "complex_callback.h";
@@ -121,11 +110,6 @@ fn MyCallback(arg: Cpp.C) -> Cpp.C;
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_pass_complex_fn_ptr.carbon:[[@LINE+5]]:27: error: call argument of type `<type of MyCallback>` is not supported [CppCallArgTypeNotSupported]
// CHECK:STDERR: Cpp.TakeComplexCallback(MyCallback);
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: error: calling function with incomplete return type 'C' [CppInteropParseError]
Cpp.TakeComplexCallback(MyCallback);
//@dump-sem-ir-end
}
@@ -170,9 +154,6 @@ library "[[@TEST_NAME]]";
import Cpp library "forward_decl.h";
fn F() {
// CHECK:STDERR: fail_use_forward_decl.carbon:[[@LINE+16]]:3: note: in thunk for C++ function used here [InCppThunk]
// CHECK:STDERR: Cpp.ReturnCallback()();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_use_forward_decl.carbon:[[@LINE+13]]:3: note: in thunk for C++ function pointer type used here [InCppFunctionPointerThunk]
// CHECK:STDERR: Cpp.ReturnCallback()();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~
@@ -180,7 +161,7 @@ fn F() {
// CHECK:STDERR: fail_use_forward_decl.carbon:[[@LINE+9]]:3: error: function returns incomplete type `Cpp.C` [IncompleteTypeInFunctionReturnType]
// CHECK:STDERR: Cpp.ReturnCallback()();
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_use_forward_decl.carbon:[[@LINE-13]]:10: in file included here [InCppInclude]
// CHECK:STDERR: fail_use_forward_decl.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./forward_decl.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR: class C;
// CHECK:STDERR: ^
@@ -189,6 +170,43 @@ fn F() {
Cpp.ReturnCallback()();
}
// --- fail_convert_generic_arg.carbon
library "[[@TEST_NAME]]";
import Cpp inline '''c++
using MyCallbackType = void(*)(int);
''';
fn MyCallback(generic arg: i32);
fn F() {
// CHECK:STDERR: fail_convert_generic_arg.carbon:[[@LINE+4]]:43: error: semantics TODO: `binding maps to a non-type template parameter` [SemanticsTodo]
// CHECK:STDERR: var unused fn_ptr: Cpp.MyCallbackType = MyCallback;
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
var unused fn_ptr: Cpp.MyCallbackType = MyCallback;
}
// --- fail_convert_type_mismatch.carbon
library "[[@TEST_NAME]]";
import Cpp inline '''c++
using MyCallbackType = void(*)(int);
''';
fn MyCallback(arg: i32) -> i32;
fn F() {
// CHECK:STDERR: fail_convert_type_mismatch.carbon:[[@LINE+7]]:43: error: can't convert exported function type to `void (int)` [ExportedFunctionPtrTypeMismatch]
// CHECK:STDERR: var unused fn_ptr: Cpp.MyCallbackType = MyCallback;
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR: fail_convert_type_mismatch.carbon:[[@LINE-6]]:1: note: function exported with type `int (int)` [ExportedFromFunction]
// CHECK:STDERR: fn MyCallback(arg: i32) -> i32;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
var unused fn_ptr: Cpp.MyCallbackType = MyCallback;
}
// CHECK:STDOUT: --- relay_fn_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -238,24 +256,36 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_convert_fn_ptr.carbon
// CHECK:STDOUT: --- convert_fn_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %f32.c73: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %MyCallback.type: type = fn_type @MyCallback [concrete]
// CHECK:STDOUT: %MyCallback: %MyCallback.type = struct_value () [concrete]
// CHECK:STDOUT: %.659: type = cpp_fn_ptr_type clang_function_pointer_type41000000 [concrete]
// CHECK:STDOUT: %pattern_type.4b7: type = pattern_type %.659 [concrete]
// CHECK:STDOUT: %fn_ptr.patt: %pattern_type.4b7 = ref_binding_pattern fn_ptr [concrete]
// CHECK:STDOUT: %fn_ptr.var_patt: %pattern_type.4b7 = var_pattern %fn_ptr.patt [concrete]
// CHECK:STDOUT: %.fc9: %.659 = cpp_addr_of_fn %MyCallback, @MyCallback [concrete]
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.type.7f5: type = fn_type @Copy.WithSelf.Op.2 [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.416: %Copy.WithSelf.Op.type.7f5 = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.bab: <witness> = custom_witness (%Copy.WithSelf.Op.416), @Copy [concrete]
// CHECK:STDOUT: %Copy.facet.8df: %Copy.type = facet_value %.659, (%custom_witness.bab) [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.type.adb: type = fn_type @Copy.WithSelf.Op.1, @Copy.WithSelf(%Copy.facet.8df) [concrete]
// CHECK:STDOUT: %.e6b: type = fn_type_with_self_type %Copy.WithSelf.Op.type.adb, %Copy.facet.8df [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.bound: <bound method> = bound_method %.fc9, %Copy.WithSelf.Op.416 [concrete]
// CHECK:STDOUT: %self.param_patt.952: %pattern_type.4b7 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.a35: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt.952 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -267,14 +297,14 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc9 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.4b7 = ref_param_pattern [concrete = constants.%self.param_patt.952]
// CHECK:STDOUT: %self.patt: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a35]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.659 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.659 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc13 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc9 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.4b7 = ref_param_pattern [concrete = constants.%self.param_patt.952]
// CHECK:STDOUT: %self.patt: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a35]
// CHECK:STDOUT: } {
@@ -287,8 +317,14 @@ fn F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %fn_ptr.var: ref %.659 = var_storage %fn_ptr.var_patt
// CHECK:STDOUT: %MyCallback.ref: %MyCallback.type = name_ref MyCallback, file.%MyCallback.decl [concrete = constants.%MyCallback]
// CHECK:STDOUT: assign %fn_ptr.var, <error>
// CHECK:STDOUT: %.loc13: type = splice_block %CallbackType.ref [concrete = constants.%.659] {
// CHECK:STDOUT: %.loc9_3.1: %.659 = cpp_addr_of_fn %MyCallback.ref, @MyCallback [concrete = constants.%.fc9]
// CHECK:STDOUT: %.loc9_3.2: %.659 = converted %MyCallback.ref, %.loc9_3.1 [concrete = constants.%.fc9]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %impl.elem0: %.e6b = impl_witness_access constants.%custom_witness.bab, element0 [concrete = constants.%Copy.WithSelf.Op.416]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc9_3.2, %impl.elem0 [concrete = constants.%Copy.WithSelf.Op.bound]
// CHECK:STDOUT: %Copy.WithSelf.Op.call: init %.659 = call %bound_method(%.loc9_3.2) [concrete = constants.%.fc9]
// CHECK:STDOUT: assign %fn_ptr.var, %Copy.WithSelf.Op.call
// CHECK:STDOUT: %.loc9_25: type = splice_block %CallbackType.ref [concrete = constants.%.659] {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %CallbackType.ref: type = name_ref CallbackType, constants.%.659 [concrete = constants.%.659]
// CHECK:STDOUT: }
@@ -302,25 +338,39 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT: fn @MyCallback__carbon_thunk(%_.param.loc9_41.1: ref %f32.c73, %_.param.loc9_41.2: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc9: %f32.c73 = acquire_value %_.param.loc9_41.1
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: assign %_.param.loc9_41.2, %MyCallback.call
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc9(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13(%self.param: ref %.659) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc9(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc9(%self.param: ref %.659) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_pass_fn_ptr.carbon
// CHECK:STDOUT: --- pass_fn_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %MyCallback.type: type = fn_type @MyCallback [concrete]
// CHECK:STDOUT: %MyCallback: %MyCallback.type = struct_value () [concrete]
// CHECK:STDOUT: %TakeCallback.cpp_overload_set.type: type = cpp_overload_set_type @TakeCallback.cpp_overload_set [concrete]
// CHECK:STDOUT: %TakeCallback.cpp_overload_set.value: %TakeCallback.cpp_overload_set.type = cpp_overload_set_value @TakeCallback.cpp_overload_set [concrete]
// CHECK:STDOUT: %.659: type = cpp_fn_ptr_type clang_function_pointer_type61000000 [concrete]
// CHECK:STDOUT: %TakeCallback.type: type = fn_type @TakeCallback [concrete]
// CHECK:STDOUT: %TakeCallback: %TakeCallback.type = struct_value () [concrete]
// CHECK:STDOUT: %.fc9: %.659 = cpp_addr_of_fn %MyCallback, @MyCallback [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -329,6 +379,11 @@ fn F() {
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %TakeCallback.cpp_overload_set.value: %TakeCallback.cpp_overload_set.type = cpp_overload_set_value @TakeCallback.cpp_overload_set [concrete = constants.%TakeCallback.cpp_overload_set.value]
// CHECK:STDOUT: %TakeCallback.decl: %TakeCallback.type = fn_decl @TakeCallback [concrete = constants.%TakeCallback] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
@@ -336,6 +391,9 @@ fn F() {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakeCallback.ref: %TakeCallback.cpp_overload_set.type = name_ref TakeCallback, imports.%TakeCallback.cpp_overload_set.value [concrete = constants.%TakeCallback.cpp_overload_set.value]
// CHECK:STDOUT: %MyCallback.ref: %MyCallback.type = name_ref MyCallback, file.%MyCallback.decl [concrete = constants.%MyCallback]
// CHECK:STDOUT: %.loc9_20.1: %.659 = cpp_addr_of_fn %MyCallback.ref, @MyCallback [concrete = constants.%.fc9]
// CHECK:STDOUT: %.loc9_20.2: %.659 = converted %MyCallback.ref, %.loc9_20.1 [concrete = constants.%.fc9]
// CHECK:STDOUT: %TakeCallback.call: init %empty_tuple.type = call imports.%TakeCallback.decl(%.loc9_20.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -569,7 +627,7 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_convert_complex_fn_ptr.carbon
// CHECK:STDOUT: --- convert_complex_fn_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
@@ -581,13 +639,22 @@ fn F() {
// CHECK:STDOUT: %pattern_type.4b7: type = pattern_type %.659 [concrete]
// CHECK:STDOUT: %fn_ptr.patt: %pattern_type.4b7 = ref_binding_pattern fn_ptr [concrete]
// CHECK:STDOUT: %fn_ptr.var_patt: %pattern_type.4b7 = var_pattern %fn_ptr.patt [concrete]
// CHECK:STDOUT: %.fc9: %.659 = cpp_addr_of_fn %MyCallback, @MyCallback [concrete]
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.type.7f5: type = fn_type @Copy.WithSelf.Op.2 [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.416: %Copy.WithSelf.Op.type.7f5 = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.bab: <witness> = custom_witness (%Copy.WithSelf.Op.416), @Copy [concrete]
// CHECK:STDOUT: %Copy.facet.8df: %Copy.type = facet_value %.659, (%custom_witness.bab) [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.type.adb: type = fn_type @Copy.WithSelf.Op.1, @Copy.WithSelf(%Copy.facet.8df) [concrete]
// CHECK:STDOUT: %.e6b: type = fn_type_with_self_type %Copy.WithSelf.Op.type.adb, %Copy.facet.8df [concrete]
// CHECK:STDOUT: %Copy.WithSelf.Op.bound: <bound method> = bound_method %.fc9, %Copy.WithSelf.Op.416 [concrete]
// CHECK:STDOUT: %self.param_patt.952: %pattern_type.4b7 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.a35: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt.952 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc13 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc9 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -601,14 +668,14 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc9 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.4b7 = ref_param_pattern [concrete = constants.%self.param_patt.952]
// CHECK:STDOUT: %self.patt: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a35]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.659 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.659 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc13 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc9 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.4b7 = ref_param_pattern [concrete = constants.%self.param_patt.952]
// CHECK:STDOUT: %self.patt: %pattern_type.4b7 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a35]
// CHECK:STDOUT: } {
@@ -621,8 +688,14 @@ fn F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %fn_ptr.var: ref %.659 = var_storage %fn_ptr.var_patt
// CHECK:STDOUT: %MyCallback.ref: %MyCallback.type = name_ref MyCallback, file.%MyCallback.decl [concrete = constants.%MyCallback]
// CHECK:STDOUT: assign %fn_ptr.var, <error>
// CHECK:STDOUT: %.loc13: type = splice_block %CallbackType.ref [concrete = constants.%.659] {
// CHECK:STDOUT: %.loc9_3.1: %.659 = cpp_addr_of_fn %MyCallback.ref, @MyCallback [concrete = constants.%.fc9]
// CHECK:STDOUT: %.loc9_3.2: %.659 = converted %MyCallback.ref, %.loc9_3.1 [concrete = constants.%.fc9]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %impl.elem0: %.e6b = impl_witness_access constants.%custom_witness.bab, element0 [concrete = constants.%Copy.WithSelf.Op.416]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc9_3.2, %impl.elem0 [concrete = constants.%Copy.WithSelf.Op.bound]
// CHECK:STDOUT: %Copy.WithSelf.Op.call: init %.659 = call %bound_method(%.loc9_3.2) [concrete = constants.%.fc9]
// CHECK:STDOUT: assign %fn_ptr.var, %Copy.WithSelf.Op.call
// CHECK:STDOUT: %.loc9_25: type = splice_block %CallbackType.ref [concrete = constants.%.659] {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %CallbackType.ref: type = name_ref CallbackType, constants.%.659 [concrete = constants.%.659]
// CHECK:STDOUT: }
@@ -636,26 +709,41 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT: fn @MyCallback__carbon_thunk(%_.param.loc9_41.1: ref %C, %_.param.loc9_41.2: ref %C) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc9_41.1: ref %C = splice_block %_.param.loc9_41.2 {}
// CHECK:STDOUT: %.loc9_41.2: %C = acquire_value %_.param.loc9_41.1
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: assign %_.param.loc9_41.2, %MyCallback.call
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc9(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13(%self.param: ref %.659) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc9(%self.param: ref %.659) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc9(%self.param: ref %.659) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_pass_complex_fn_ptr.carbon
// CHECK:STDOUT: --- pass_complex_fn_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %MyCallback.type: type = fn_type @MyCallback [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %MyCallback: %MyCallback.type = struct_value () [concrete]
// CHECK:STDOUT: %TakeComplexCallback.cpp_overload_set.type: type = cpp_overload_set_type @TakeComplexCallback.cpp_overload_set [concrete]
// CHECK:STDOUT: %TakeComplexCallback.cpp_overload_set.value: %TakeComplexCallback.cpp_overload_set.type = cpp_overload_set_value @TakeComplexCallback.cpp_overload_set [concrete]
// CHECK:STDOUT: %.659: type = cpp_fn_ptr_type clang_function_pointer_type69000000 [concrete]
// CHECK:STDOUT: %TakeComplexCallback.type: type = fn_type @TakeComplexCallback [concrete]
// CHECK:STDOUT: %TakeComplexCallback: %TakeComplexCallback.type = struct_value () [concrete]
// CHECK:STDOUT: %.fc9: %.659 = cpp_addr_of_fn %MyCallback, @MyCallback [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -666,6 +754,11 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
// CHECK:STDOUT: %TakeComplexCallback.cpp_overload_set.value: %TakeComplexCallback.cpp_overload_set.type = cpp_overload_set_value @TakeComplexCallback.cpp_overload_set [concrete = constants.%TakeComplexCallback.cpp_overload_set.value]
// CHECK:STDOUT: %TakeComplexCallback.decl: %TakeComplexCallback.type = fn_decl @TakeComplexCallback [concrete = constants.%TakeComplexCallback] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
@@ -673,6 +766,9 @@ fn F() {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %TakeComplexCallback.ref: %TakeComplexCallback.cpp_overload_set.type = name_ref TakeComplexCallback, imports.%TakeComplexCallback.cpp_overload_set.value [concrete = constants.%TakeComplexCallback.cpp_overload_set.value]
// CHECK:STDOUT: %MyCallback.ref: %MyCallback.type = name_ref MyCallback, file.%MyCallback.decl [concrete = constants.%MyCallback]
// CHECK:STDOUT: %.loc9_27.1: %.659 = cpp_addr_of_fn %MyCallback.ref, @MyCallback [concrete = constants.%.fc9]
// CHECK:STDOUT: %.loc9_27.2: %.659 = converted %MyCallback.ref, %.loc9_27.1 [concrete = constants.%.fc9]
// CHECK:STDOUT: %TakeComplexCallback.call: init %empty_tuple.type = call imports.%TakeComplexCallback.decl(%.loc9_27.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: