Make Destroy.Op functions able to have a body (#6729)

This is iterating on how `Destroy.Op` generates, to start adding body
capabilities. This changes the way the signature is created, and adds a
`CoreWitness` function kind so that mangling can prevent name
collisions. The result is that what _was_ `DestroyOp` is now
`Core.Destroy.Op` or, as can be seen in
toolchain/lower/testdata/interop/cpp/nullptr.carbon,
`_COp.<hash>:core.Destroy.Core` where `:core` is indicating that it's a
core witness (taking a note from `:thunk`).

Assisted-by: Google Antigravity with Gemini 3 Flash
This commit is contained in:
Jon Ross-Perkins
2026-03-02 17:57:31 +00:00
committed by GitHub
parent 2389590230
commit b14015602b
163 changed files with 2472 additions and 2339 deletions
+5 -5
View File
@@ -32,8 +32,8 @@ fn Main() {
// CHECK:STDOUT: %Main.type: type = fn_type @Main [concrete]
// CHECK:STDOUT: %Main: %Main.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -91,10 +91,10 @@ fn Main() {
// CHECK:STDOUT: %.loc20_18.3: type = converted %.loc20_18.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %empty_tuple.type = ref_binding b, %b.var
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %b.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%b.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %b.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%b.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
@@ -62,8 +62,8 @@ fn Run() {
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -127,10 +127,10 @@ fn Run() {
// CHECK:STDOUT: assign %x.var, <error>
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %x: ref %i32 = ref_binding x, %x.var
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %x.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%x.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %x.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%x.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
+5 -5
View File
@@ -275,8 +275,8 @@ fn F() ->? ref i32;
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -313,12 +313,12 @@ fn F() ->? ref i32;
// CHECK:STDOUT: %.loc4_7.2: init %i32 = converted %int_0, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9]
// CHECK:STDOUT: %.loc4_7.3: ref %i32 = temporary %.loc4_7.1, %.loc4_7.2
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%.loc4_7.3)
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %.loc4_7.3, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc4_7.3)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.loc4_7.3, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc4_7.3)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: --- val_form_param.carbon
// CHECK:STDOUT:
+5 -5
View File
@@ -63,8 +63,8 @@ fn Main() {
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -141,10 +141,10 @@ fn Main() {
// CHECK:STDOUT: assign %b.var, %Echo.call
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %b: ref %i32 = ref_binding b, %b.var
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %b.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%b.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %b.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%b.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
@@ -63,8 +63,8 @@ fn Main() {
// CHECK:STDOUT: %bound_method.bc2: <bound method> = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_6.e56: %i32 = int_value 6 [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -148,10 +148,10 @@ fn Main() {
// CHECK:STDOUT: %.loc20_12.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc20 [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %.loc20_12.2: %i32 = converted %int_6, %.loc20_12.1 [concrete = constants.%int_6.e56]
// CHECK:STDOUT: %Foo.call: init %empty_tuple.type = call %Foo.ref(%.loc20_8, %.loc20_12.2)
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %x.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%x.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %x.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%x.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %tuple.type.a1c) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %tuple.type.a1c) = "no_op";
// CHECK:STDOUT:
+10 -10
View File
@@ -127,8 +127,8 @@ fn G() {
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -171,12 +171,12 @@ fn G() {
// CHECK:STDOUT: %y.ref: ref %i32 = name_ref y, %y
// CHECK:STDOUT: %.loc10: %i32 = ref_tag %y.ref
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%.loc10)
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %y.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%y.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %y.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%y.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: --- class.carbon
// CHECK:STDOUT:
@@ -190,8 +190,8 @@ fn G() {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -231,10 +231,10 @@ fn G() {
// CHECK:STDOUT: %F.ref: %C.F.type = name_ref F, @C.%C.F.decl [concrete = constants.%C.F]
// CHECK:STDOUT: %C.F.bound: <bound method> = bound_method %c.ref, %F.ref
// CHECK:STDOUT: %C.F.call: init %empty_tuple.type = call %C.F.bound(%c.ref)
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %c.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%c.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %c.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%c.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %C) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %C) = "no_op";
// CHECK:STDOUT:
@@ -30,8 +30,8 @@ fn Main() {
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -74,10 +74,10 @@ fn Main() {
// CHECK:STDOUT: %.loc19_18.3: type = converted %.loc19_18.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %empty_tuple.type = ref_binding b, %b.var
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %b.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%b.var)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %b.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%b.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
@@ -217,8 +217,8 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT: %ReturnDUsed.type: type = fn_type @ReturnDUsed [concrete]
// CHECK:STDOUT: %ReturnDUsed: %ReturnDUsed.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -279,10 +279,10 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT: %.loc34_15.1: ref %D = temporary_storage
// CHECK:STDOUT: %ReturnDUsed.call: init %D to %.loc34_15.1 = call %ReturnDUsed.ref()
// CHECK:STDOUT: %.loc34_15.2: ref %D = temporary %.loc34_15.1, %ReturnDUsed.call
// CHECK:STDOUT: %DestroyOp.bound.loc34: <bound method> = bound_method %.loc34_15.2, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call.loc34: init %empty_tuple.type = call %DestroyOp.bound.loc34(%.loc34_15.2)
// CHECK:STDOUT: %DestroyOp.bound.loc33: <bound method> = bound_method %.loc33_17.2, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call.loc33: init %empty_tuple.type = call %DestroyOp.bound.loc33(%.loc33_17.2)
// CHECK:STDOUT: %Destroy.Op.bound.loc34: <bound method> = bound_method %.loc34_15.2, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call.loc34: init %empty_tuple.type = call %Destroy.Op.bound.loc34(%.loc34_15.2)
// CHECK:STDOUT: %Destroy.Op.bound.loc33: <bound method> = bound_method %.loc33_17.2, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call.loc33: init %empty_tuple.type = call %Destroy.Op.bound.loc33(%.loc33_17.2)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -294,5 +294,5 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @ReturnDUsed [from "fail_incomplete_return.carbon"];
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %D) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %D) = "no_op";
// CHECK:STDOUT:
@@ -104,8 +104,8 @@ fn F() {
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -148,12 +148,12 @@ fn F() {
// CHECK:STDOUT: %.loc14_28.3: type = converted %.loc14_28.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %w: ref %empty_struct_type = ref_binding w, %w.var
// CHECK:STDOUT: %DestroyOp.bound.loc14: <bound method> = bound_method %w.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call.loc14: init %empty_tuple.type = call %DestroyOp.bound.loc14(%w.var)
// CHECK:STDOUT: %DestroyOp.bound.loc9: <bound method> = bound_method %v.var, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call.loc9: init %empty_tuple.type = call %DestroyOp.bound.loc9(%v.var)
// CHECK:STDOUT: %Destroy.Op.bound.loc14: <bound method> = bound_method %w.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call.loc14: init %empty_tuple.type = call %Destroy.Op.bound.loc14(%w.var)
// CHECK:STDOUT: %Destroy.Op.bound.loc9: <bound method> = bound_method %v.var, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call.loc9: init %empty_tuple.type = call %Destroy.Op.bound.loc9(%v.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
+5 -5
View File
@@ -563,8 +563,8 @@ fn F() {
// CHECK:STDOUT: %ExplicitAndAlsoDeduced.specific_fn.1f3: <specific function> = specific_function %ExplicitAndAlsoDeduced, @ExplicitAndAlsoDeduced(%A) [concrete]
// CHECK:STDOUT: %A.val: %A = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: %complete_type.8a0: <witness> = complete_type_witness %ptr.643 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -662,12 +662,12 @@ fn F() {
// CHECK:STDOUT: %.loc11_37.5: ref %A = converted %.loc11_37.1, %.loc11_37.4
// CHECK:STDOUT: %.loc11_37.6: %A = acquire_value %.loc11_37.5
// CHECK:STDOUT: %ExplicitAndAlsoDeduced.call: init %ptr.643 = call %ExplicitAndAlsoDeduced.specific_fn(%.loc11_37.6)
// CHECK:STDOUT: %DestroyOp.bound: <bound method> = bound_method %.loc11_37.4, constants.%DestroyOp
// CHECK:STDOUT: %DestroyOp.call: init %empty_tuple.type = call %DestroyOp.bound(%.loc11_37.4)
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.loc11_37.4, constants.%Destroy.Op
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc11_37.4)
// CHECK:STDOUT: return %ExplicitAndAlsoDeduced.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %A) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %A) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: specific @ExplicitAndAlsoDeduced(constants.%T) {
// CHECK:STDOUT: %T.loc6_27.1 => constants.%T
+13 -13
View File
@@ -69,12 +69,12 @@ fn CallNegative() {
// CHECK:STDOUT: %i0: type = class_type @Int, @Int(%int_0) [concrete]
// CHECK:STDOUT: %complete_type.d94: <witness> = complete_type_witness <error> [concrete]
// CHECK:STDOUT: %pattern_type.47b: type = pattern_type %i0 [concrete]
// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete]
// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.809: <witness> = custom_witness (%DestroyOp), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.7e1: %Destroy.type = facet_value %i0, (%custom_witness.809) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.e5a: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet.7e1) [concrete]
// CHECK:STDOUT: %.011: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.e5a, %Destroy.facet.7e1 [concrete]
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.8d7: <witness> = custom_witness (%Destroy.Op), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.eb2: %Destroy.type = facet_value %i0, (%custom_witness.8d7) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.cef: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet.eb2) [concrete]
// CHECK:STDOUT: %.98d: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.cef, %Destroy.facet.eb2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -159,7 +159,7 @@ fn CallNegative() {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp(%self.param: ref %i0) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op(%self.param: ref %i0) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: specific @ErrorIfNIsZero(constants.%N) {
// CHECK:STDOUT: %N.loc4_19.1 => constants.%N
@@ -172,11 +172,11 @@ fn CallNegative() {
// CHECK:STDOUT: %Int.loc9_27.2 => constants.%i0
// CHECK:STDOUT: %require_complete => constants.%complete_type.d94
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.47b
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%custom_witness.809
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.7e1
// CHECK:STDOUT: %Destroy.WithSelf.Op.type => constants.%Destroy.WithSelf.Op.type.e5a
// CHECK:STDOUT: %.loc9_3 => constants.%.011
// CHECK:STDOUT: %impl.elem0.loc9_3.2 => constants.%DestroyOp
// CHECK:STDOUT: %specific_impl_fn.loc9_3.2 => constants.%DestroyOp
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%custom_witness.8d7
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.eb2
// CHECK:STDOUT: %Destroy.WithSelf.Op.type => constants.%Destroy.WithSelf.Op.type.cef
// CHECK:STDOUT: %.loc9_3 => constants.%.98d
// CHECK:STDOUT: %impl.elem0.loc9_3.2 => constants.%Destroy.Op
// CHECK:STDOUT: %specific_impl_fn.loc9_3.2 => constants.%Destroy.Op
// CHECK:STDOUT: }
// CHECK:STDOUT:
+15 -15
View File
@@ -77,12 +77,12 @@ fn G() {
// CHECK:STDOUT: %.768: Core.Form = init_form %C, call_param0 [concrete]
// CHECK:STDOUT: %Wrap.Make.specific_fn.cb9: <specific function> = specific_function %Wrap.Make.62a, @Wrap.Make(%C) [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %DestroyOp.type.3e79c2.1: type = fn_type @DestroyOp.loc24 [concrete]
// CHECK:STDOUT: %DestroyOp.b0ebf8.1: %DestroyOp.type.3e79c2.1 = struct_value () [concrete]
// CHECK:STDOUT: %DestroyOp.type.3e79c2.2: type = fn_type @DestroyOp.loc23 [concrete]
// CHECK:STDOUT: %DestroyOp.b0ebf8.2: %DestroyOp.type.3e79c2.2 = struct_value () [concrete]
// CHECK:STDOUT: %DestroyOp.type.3e79c2.3: type = fn_type @DestroyOp.loc22 [concrete]
// CHECK:STDOUT: %DestroyOp.b0ebf8.3: %DestroyOp.type.3e79c2.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type.bae255.1: type = fn_type @Destroy.Op.loc24 [concrete]
// CHECK:STDOUT: %Destroy.Op.651ba6.1: %Destroy.Op.type.bae255.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type.bae255.2: type = fn_type @Destroy.Op.loc23 [concrete]
// CHECK:STDOUT: %Destroy.Op.651ba6.2: %Destroy.Op.type.bae255.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type.bae255.3: type = fn_type @Destroy.Op.loc22 [concrete]
// CHECK:STDOUT: %Destroy.Op.651ba6.3: %Destroy.Op.type.bae255.3 = struct_value () [concrete]
// CHECK:STDOUT: %complete_type.782: <witness> = complete_type_witness %empty_tuple.type [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -232,20 +232,20 @@ fn G() {
// CHECK:STDOUT: assign %c.var, %Wrap.Make.call.loc24
// CHECK:STDOUT: %C.ref.loc24_17: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %c: ref %C = ref_binding c, %c.var
// CHECK:STDOUT: %DestroyOp.bound.loc24: <bound method> = bound_method %c.var, constants.%DestroyOp.b0ebf8.1
// CHECK:STDOUT: %DestroyOp.call.loc24: init %empty_tuple.type = call %DestroyOp.bound.loc24(%c.var)
// CHECK:STDOUT: %DestroyOp.bound.loc23: <bound method> = bound_method %b.var, constants.%DestroyOp.b0ebf8.2
// CHECK:STDOUT: %DestroyOp.call.loc23: init %empty_tuple.type = call %DestroyOp.bound.loc23(%b.var)
// CHECK:STDOUT: %DestroyOp.bound.loc22: <bound method> = bound_method %a.var, constants.%DestroyOp.b0ebf8.3
// CHECK:STDOUT: %DestroyOp.call.loc22: init %empty_tuple.type = call %DestroyOp.bound.loc22(%a.var)
// CHECK:STDOUT: %Destroy.Op.bound.loc24: <bound method> = bound_method %c.var, constants.%Destroy.Op.651ba6.1
// CHECK:STDOUT: %Destroy.Op.call.loc24: init %empty_tuple.type = call %Destroy.Op.bound.loc24(%c.var)
// CHECK:STDOUT: %Destroy.Op.bound.loc23: <bound method> = bound_method %b.var, constants.%Destroy.Op.651ba6.2
// CHECK:STDOUT: %Destroy.Op.call.loc23: init %empty_tuple.type = call %Destroy.Op.bound.loc23(%b.var)
// CHECK:STDOUT: %Destroy.Op.bound.loc22: <bound method> = bound_method %a.var, constants.%Destroy.Op.651ba6.3
// CHECK:STDOUT: %Destroy.Op.call.loc22: init %empty_tuple.type = call %Destroy.Op.bound.loc22(%a.var)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp.loc24(%self.param: ref %C) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op.loc24(%self.param: ref %C) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp.loc23(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op.loc23(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @DestroyOp.loc22(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT: fn @Destroy.Op.loc22(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Wrap(constants.%T) {
// CHECK:STDOUT: %T.loc15_12.1 => constants.%T