mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Generate Destroy impls for classes (#5873)
Although this focused on `Destroy` support, some choices here around `implicit_type_impls` are because copy/move will likely follow a similar approach. I'm trying not to predict too much about how we'll structure those, but I'm putting `Destroy` impl logic in a file that could perhaps be shared with those. They'd likely be interested in similar things, e.g. traversing members of types (particularly class, struct literal, tuple literal). At present this sets the destroy function as `no_op` which is consistent with current logic, but has a TODO to correctly define. Constant importing for functions changes slightly due to some issues I was having with `GetFunctionType`. zygoloid suggested this approach to avoid `EvalInst` logic. Adds a flag for controlling whether to generating these impls. While this does generation for `class`, as noted above this'll also need to be done for tuples and struct literals, which would leave the `none.carbon` min_prelude unable to use any types. Note if destruction *would* occur, it'll still look up `Core.Destroy` for that and fail, but that's already true of any test using `none.carbon`. I'm trying to use the flag to see if we can keep `none.carbon` working mostly-consistently. I'd tried separating out the flag to #5852, but that got a lot of pushback over whether the behavior was appropriate. I'm hoping that the interactions here make it clearer why the particular approach -- the goal is not to enable advanced testing, or create some new end-user behavior that we really support, it's just to keep no-prelude tests functional. The main question raised there was why not just keep generating `impl T as Core.Destroy` if `fn destroy` is present -- but I think here it should be apparent that would require additional complexity, as the generation of `impl T as Core.Destroy` is not currently conditioned based on the implementation of `fn destroy`. I'd rather add complexity to this flag only if it's enabling interesting test functionality. --------- Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
co-authored by
Geoff Romer
parent
a5a5e381be
commit
7209ad7c9f
+209
-41
@@ -102,10 +102,28 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %A.assoc_type.ed3: type = assoc_entity_type @A, @A(%T.8b3) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.fcb: %A.assoc_type.ed3 = assoc_entity element0, @A.%A.F.decl [symbolic]
|
||||
// CHECK:STDOUT: %X: type = class_type @X [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.807: <witness> = impl_witness @X.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete]
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
|
||||
// CHECK:STDOUT: %Y: type = class_type @Y [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.621: <witness> = impl_witness @Y.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.455: type = ptr_type %Y [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %ptr.455 [concrete]
|
||||
// CHECK:STDOUT: %Y.as.Destroy.impl.Op.type: type = fn_type @Y.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %Y.as.Destroy.impl.Op: %Y.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Z: type = class_type @Z [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.2a0: <witness> = impl_witness @Z.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.f76: type = pattern_type %ptr.fb6 [concrete]
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.type: type = fn_type @Z.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op: %Z.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %A.type.91f: type = facet_type <@A, @A(%X)> [concrete]
|
||||
// CHECK:STDOUT: %Self.1bb: %A.type.91f = bind_symbolic_name Self, 1 [symbolic]
|
||||
// CHECK:STDOUT: %A.F.type.13d: type = fn_type @A.F, @A(%X) [concrete]
|
||||
@@ -135,14 +153,8 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %pattern_type.ef1: type = pattern_type %tuple.type.f6b [concrete]
|
||||
// CHECK:STDOUT: %Y.as.A.impl.F.specific_fn: <specific function> = specific_function %Y.as.A.impl.F, @Y.as.A.impl.F(%Z) [concrete]
|
||||
// CHECK:STDOUT: %Z.val: %Z = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T.8b3) [symbolic]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f73: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Z) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.6e3: %T.as.Destroy.impl.Op.type.f73 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3b7: <specific function> = specific_function %T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(%Z) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.955: <witness> = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%tuple.type.f6b) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.495: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.f6b) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.51a: %T.as.Destroy.impl.Op.type.495 = struct_value () [concrete]
|
||||
@@ -150,7 +162,7 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %complete_type.456: <witness> = complete_type_witness %ptr.959 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.1f2: %Destroy.type = facet_value %tuple.type.f6b, (%Destroy.impl_witness.955) [concrete]
|
||||
// CHECK:STDOUT: %.a86: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.1f2 [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8e5: <specific function> = specific_function %T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(%tuple.type.f6b) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(%tuple.type.f6b) [concrete]
|
||||
// CHECK:STDOUT: %T.9c2: %A.type.91f = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.817: type = pattern_type %A.type.91f [concrete]
|
||||
// CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [concrete]
|
||||
@@ -276,6 +288,54 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X]
|
||||
// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @X.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Y.as.Destroy.impl: constants.%Y as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %Y.as.Destroy.impl.Op.decl: %Y.as.Destroy.impl.Op.type = fn_decl @Y.as.Destroy.impl.Op [concrete = constants.%Y.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.0ae = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.0ae = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.455 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y [concrete = constants.%Y]
|
||||
// CHECK:STDOUT: %self: %ptr.455 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %Y.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @Y.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Z.as.Destroy.impl: constants.%Z as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.decl: %Z.as.Destroy.impl.Op.type = fn_decl @Z.as.Destroy.impl.Op [concrete = constants.%Z.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.f76 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.f76 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.fb6 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Z [concrete = constants.%Z]
|
||||
// CHECK:STDOUT: %self: %ptr.fb6 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %Z.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @Z.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Y.as.A.impl: %Y.ref as %A.type {
|
||||
// CHECK:STDOUT: %Y.as.A.impl.F.decl: %Y.as.A.impl.F.type = fn_decl @Y.as.A.impl.F [concrete = constants.%Y.as.A.impl.F] {
|
||||
// CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete]
|
||||
@@ -305,6 +365,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @X {
|
||||
// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -314,6 +377,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Y {
|
||||
// CHECK:STDOUT: impl_decl @Y.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y.as.Destroy.impl.%Y.as.Destroy.impl.Op.decl), @Y.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.621]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -323,6 +389,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Z {
|
||||
// CHECK:STDOUT: impl_decl @Z.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Z.as.Destroy.impl.%Z.as.Destroy.impl.Op.decl), @Z.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a0]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -345,6 +414,12 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: fn(%u.param: @A.F.%U.loc6_8.1 (%U.2cb)) -> @A.F.%tuple.type.loc6_38.2 (%tuple.type.bd2);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Y.as.Destroy.impl.Op(%self.param: %ptr.455) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Z.as.Destroy.impl.Op(%self.param: %ptr.fb6) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @Y.as.A.impl.F(%U.loc16_8.2: type) {
|
||||
// CHECK:STDOUT: %U.loc16_8.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc16_8.1 (constants.%U.8b3)]
|
||||
// CHECK:STDOUT: %pattern_type.loc16_18: type = pattern_type %U.loc16_8.1 [symbolic = %pattern_type.loc16_18 (constants.%pattern_type.7dc)]
|
||||
@@ -400,16 +475,14 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %.loc22_21.6: %Z = bind_value %.loc22_21.5
|
||||
// CHECK:STDOUT: %Y.as.A.impl.F.call: init %tuple.type.f6b = call %specific_fn(%.loc22_21.6) to %.loc22_22.1
|
||||
// CHECK:STDOUT: %.loc22_22.2: ref %tuple.type.f6b = temporary %.loc22_22.1, %Y.as.A.impl.F.call
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_21: <bound method> = bound_method %.loc22_21.2, constants.%T.as.Destroy.impl.Op.6e3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7]
|
||||
// CHECK:STDOUT: %bound_method.loc22_21: <bound method> = bound_method %.loc22_21.2, %T.as.Destroy.impl.Op.specific_fn.1
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc22_21.2, constants.%Z.as.Destroy.impl.Op
|
||||
// CHECK:STDOUT: %addr.loc22_21: %ptr.fb6 = addr_of %.loc22_21.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_21: init %empty_tuple.type = call %bound_method.loc22_21(%addr.loc22_21)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_22: <bound method> = bound_method %.loc22_22.1, constants.%T.as.Destroy.impl.Op.51a
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(constants.%tuple.type.f6b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8e5]
|
||||
// CHECK:STDOUT: %bound_method.loc22_22: <bound method> = bound_method %.loc22_22.1, %T.as.Destroy.impl.Op.specific_fn.2
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc22_21)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc22_22.1, constants.%T.as.Destroy.impl.Op.51a
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(constants.%tuple.type.f6b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc22_22.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc22_22: %ptr.959 = addr_of %.loc22_22.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_22: init %empty_tuple.type = call %bound_method.loc22_22(%addr.loc22_22)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc22_22)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -452,11 +525,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %.loc26_11.6: %Z = bind_value %.loc26_11.5
|
||||
// CHECK:STDOUT: %.loc26_12.2: init @CallGeneric.%tuple.type (%tuple.type.e28) = call %specific_impl_fn.loc26_4.1(%.loc26_11.6) to %.loc26_12.1
|
||||
// CHECK:STDOUT: %.loc26_12.3: ref @CallGeneric.%tuple.type (%tuple.type.e28) = temporary %.loc26_12.1, %.loc26_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc26_11.2, constants.%T.as.Destroy.impl.Op.6e3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7]
|
||||
// CHECK:STDOUT: %bound_method.loc26_11: <bound method> = bound_method %.loc26_11.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc26_11.2, constants.%Z.as.Destroy.impl.Op
|
||||
// CHECK:STDOUT: %addr.loc26_11: %ptr.fb6 = addr_of %.loc26_11.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc26_11(%addr.loc26_11)
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc26_11)
|
||||
// CHECK:STDOUT: %impl.elem0.loc26_12.1: @CallGeneric.%.loc26_12.5 (%.efa) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc26_12.2 (constants.%impl.elem0.305)]
|
||||
// CHECK:STDOUT: %bound_method.loc26_12.1: <bound method> = bound_method %.loc26_12.1, %impl.elem0.loc26_12.1
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc26_12.1: <specific function> = specific_impl_function %impl.elem0.loc26_12.1, @Destroy.Op(constants.%Destroy.facet.1a6) [symbolic = %specific_impl_fn.loc26_12.2 (constants.%specific_impl_fn.52a)]
|
||||
@@ -569,7 +640,7 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.1f2
|
||||
// CHECK:STDOUT: %.loc26_12.5 => constants.%.a86
|
||||
// CHECK:STDOUT: %impl.elem0.loc26_12.2 => constants.%T.as.Destroy.impl.Op.51a
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc26_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn.8e5
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc26_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %ptr => constants.%ptr.959
|
||||
// CHECK:STDOUT: %require_complete.loc26_12.2 => constants.%complete_type.456
|
||||
// CHECK:STDOUT: }
|
||||
@@ -607,11 +678,34 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %A.assoc_type.ed3: type = assoc_entity_type @A, @A(%T.8b3) [symbolic]
|
||||
// CHECK:STDOUT: %assoc0.fcb: %A.assoc_type.ed3 = assoc_entity element0, @A.%A.F.decl [symbolic]
|
||||
// CHECK:STDOUT: %X: type = class_type @X [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.807: <witness> = impl_witness @X.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete]
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
|
||||
// CHECK:STDOUT: %Y1: type = class_type @Y1 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.614: <witness> = impl_witness @Y1.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.723: type = ptr_type %Y1 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.273: type = pattern_type %ptr.723 [concrete]
|
||||
// CHECK:STDOUT: %Y1.as.Destroy.impl.Op.type: type = fn_type @Y1.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %Y1.as.Destroy.impl.Op: %Y1.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Y2: type = class_type @Y2 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.7b0: <witness> = impl_witness @Y2.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.23d: type = ptr_type %Y2 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.484: type = pattern_type %ptr.23d [concrete]
|
||||
// CHECK:STDOUT: %Y2.as.Destroy.impl.Op.type: type = fn_type @Y2.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %Y2.as.Destroy.impl.Op: %Y2.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Z: type = class_type @Z [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.2a0: <witness> = impl_witness @Z.%Destroy.impl_witness_table [concrete]
|
||||
// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.f76: type = pattern_type %ptr.fb6 [concrete]
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.type: type = fn_type @Z.as.Destroy.impl.Op [concrete]
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op: %Z.as.Destroy.impl.Op.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %V1: type = bind_symbolic_name V1, 0 [symbolic]
|
||||
// CHECK:STDOUT: %V2: type = bind_symbolic_name V2, 1 [symbolic]
|
||||
// CHECK:STDOUT: %W: type = bind_symbolic_name W, 2 [symbolic]
|
||||
@@ -637,8 +731,6 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %require_complete.d4d: <witness> = require_complete_type %tuple.type.8ae [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.ed4: <witness> = require_complete_type %U.753 [symbolic]
|
||||
// CHECK:STDOUT: %tuple.type.as.A.impl.F.specific_fn.7d9: <specific function> = specific_function %tuple.type.as.A.impl.F.d79, @tuple.type.as.A.impl.F(%V1, %V2, %W, %U.753) [symbolic]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T.8b3) [symbolic]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %ptr.ab5: type = ptr_type %tuple.type.8ae [symbolic]
|
||||
@@ -668,10 +760,6 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %pattern_type.0b2: type = pattern_type %tuple.type.415 [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.as.A.impl.F.specific_fn.79b: <specific function> = specific_function %tuple.type.as.A.impl.F.93b, @tuple.type.as.A.impl.F(%Y1, %Y2, %X, %Z) [concrete]
|
||||
// CHECK:STDOUT: %Z.val: %Z = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f73: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Z) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.6e3: %T.as.Destroy.impl.Op.type.f73 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3b7: <specific function> = specific_function %T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(%Z) [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness.c80: <witness> = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%tuple.type.415) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.2a3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.415) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.66e: %T.as.Destroy.impl.Op.type.2a3 = struct_value () [concrete]
|
||||
@@ -679,7 +767,7 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %complete_type.e23: <witness> = complete_type_witness %ptr.ad9 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.facet.2b1: %Destroy.type = facet_value %tuple.type.415, (%Destroy.impl_witness.c80) [concrete]
|
||||
// CHECK:STDOUT: %.1b7: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.2b1 [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.ce9: <specific function> = specific_function %T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(%tuple.type.415) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(%tuple.type.415) [concrete]
|
||||
// CHECK:STDOUT: %T.9c2: %A.type.91f = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: %pattern_type.817: type = pattern_type %A.type.91f [concrete]
|
||||
// CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [concrete]
|
||||
@@ -817,6 +905,70 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X]
|
||||
// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @X.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Y1.as.Destroy.impl: constants.%Y1 as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %Y1.as.Destroy.impl.Op.decl: %Y1.as.Destroy.impl.Op.type = fn_decl @Y1.as.Destroy.impl.Op [concrete = constants.%Y1.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.273 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.273 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.723 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y1 [concrete = constants.%Y1]
|
||||
// CHECK:STDOUT: %self: %ptr.723 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %Y1.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @Y1.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Y2.as.Destroy.impl: constants.%Y2 as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %Y2.as.Destroy.impl.Op.decl: %Y2.as.Destroy.impl.Op.type = fn_decl @Y2.as.Destroy.impl.Op [concrete = constants.%Y2.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.484 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.484 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.23d = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y2 [concrete = constants.%Y2]
|
||||
// CHECK:STDOUT: %self: %ptr.23d = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %Y2.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @Y2.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl @Z.as.Destroy.impl: constants.%Z as constants.%Destroy.type {
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.decl: %Z.as.Destroy.impl.Op.type = fn_decl @Z.as.Destroy.impl.Op [concrete = constants.%Z.as.Destroy.impl.Op] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.f76 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.f76 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.fb6 = value_param call_param0
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Z [concrete = constants.%Z]
|
||||
// CHECK:STDOUT: %self: %ptr.fb6 = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Op = %Z.as.Destroy.impl.Op.decl
|
||||
// CHECK:STDOUT: witness = @Z.%Destroy.impl_witness
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic impl @tuple.type.as.A.impl(%V1.loc14_14.2: type, %V2.loc14_25.2: type, %W.loc14_36.2: type) {
|
||||
// CHECK:STDOUT: %V1.loc14_14.1: type = bind_symbolic_name V1, 0 [symbolic = %V1.loc14_14.1 (constants.%V1)]
|
||||
// CHECK:STDOUT: %V2.loc14_25.1: type = bind_symbolic_name V2, 1 [symbolic = %V2.loc14_25.1 (constants.%V2)]
|
||||
@@ -864,6 +1016,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @X {
|
||||
// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -873,6 +1028,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Y1 {
|
||||
// CHECK:STDOUT: impl_decl @Y1.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y1.as.Destroy.impl.%Y1.as.Destroy.impl.Op.decl), @Y1.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.614]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -882,6 +1040,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Y2 {
|
||||
// CHECK:STDOUT: impl_decl @Y2.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y2.as.Destroy.impl.%Y2.as.Destroy.impl.Op.decl), @Y2.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.7b0]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -891,6 +1052,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Z {
|
||||
// CHECK:STDOUT: impl_decl @Z.as.Destroy.impl [concrete] {} {}
|
||||
// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Z.as.Destroy.impl.%Z.as.Destroy.impl.Op.decl), @Z.as.Destroy.impl [concrete]
|
||||
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a0]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
@@ -913,6 +1077,14 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: fn(%u.param: @A.F.%U.loc6_8.1 (%U.2cb)) -> @A.F.%tuple.type.loc6_38.2 (%tuple.type.bd2);
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Y1.as.Destroy.impl.Op(%self.param: %ptr.723) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Y2.as.Destroy.impl.Op(%self.param: %ptr.23d) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Z.as.Destroy.impl.Op(%self.param: %ptr.fb6) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic fn @tuple.type.as.A.impl.F(@tuple.type.as.A.impl.%V1.loc14_14.2: type, @tuple.type.as.A.impl.%V2.loc14_25.2: type, @tuple.type.as.A.impl.%W.loc14_36.2: type, %U.loc17_8.2: type) {
|
||||
// CHECK:STDOUT: %U.loc17_8.1: type = bind_symbolic_name U, 3 [symbolic = %U.loc17_8.1 (constants.%U.753)]
|
||||
// CHECK:STDOUT: %pattern_type.loc17_18: type = pattern_type %U.loc17_8.1 [symbolic = %pattern_type.loc17_18 (constants.%pattern_type.549)]
|
||||
@@ -983,16 +1155,14 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %.loc24_38.6: %Z = bind_value %.loc24_38.5
|
||||
// CHECK:STDOUT: %tuple.type.as.A.impl.F.call: init %tuple.type.415 = call %specific_fn(%.loc24_38.6) to %.loc24_39.1
|
||||
// CHECK:STDOUT: %.loc24_39.2: ref %tuple.type.415 = temporary %.loc24_39.1, %tuple.type.as.A.impl.F.call
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_38: <bound method> = bound_method %.loc24_38.2, constants.%T.as.Destroy.impl.Op.6e3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7]
|
||||
// CHECK:STDOUT: %bound_method.loc24_38: <bound method> = bound_method %.loc24_38.2, %T.as.Destroy.impl.Op.specific_fn.1
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc24_38.2, constants.%Z.as.Destroy.impl.Op
|
||||
// CHECK:STDOUT: %addr.loc24_38: %ptr.fb6 = addr_of %.loc24_38.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_38: init %empty_tuple.type = call %bound_method.loc24_38(%addr.loc24_38)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_39: <bound method> = bound_method %.loc24_39.1, constants.%T.as.Destroy.impl.Op.66e
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(constants.%tuple.type.415) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.ce9]
|
||||
// CHECK:STDOUT: %bound_method.loc24_39: <bound method> = bound_method %.loc24_39.1, %T.as.Destroy.impl.Op.specific_fn.2
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc24_38)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc24_39.1, constants.%T.as.Destroy.impl.Op.66e
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(constants.%tuple.type.415) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc24_39.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc24_39: %ptr.ad9 = addr_of %.loc24_39.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_39: init %empty_tuple.type = call %bound_method.loc24_39(%addr.loc24_39)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc24_39)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -1035,11 +1205,9 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %.loc28_11.6: %Z = bind_value %.loc28_11.5
|
||||
// CHECK:STDOUT: %.loc28_12.2: init @CallGeneric.%tuple.type (%tuple.type.e28) = call %specific_impl_fn.loc28_4.1(%.loc28_11.6) to %.loc28_12.1
|
||||
// CHECK:STDOUT: %.loc28_12.3: ref @CallGeneric.%tuple.type (%tuple.type.e28) = temporary %.loc28_12.1, %.loc28_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc28_11.2, constants.%T.as.Destroy.impl.Op.6e3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7]
|
||||
// CHECK:STDOUT: %bound_method.loc28_11: <bound method> = bound_method %.loc28_11.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc28_11.2, constants.%Z.as.Destroy.impl.Op
|
||||
// CHECK:STDOUT: %addr.loc28_11: %ptr.fb6 = addr_of %.loc28_11.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc28_11(%addr.loc28_11)
|
||||
// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc28_11)
|
||||
// CHECK:STDOUT: %impl.elem0.loc28_12.1: @CallGeneric.%.loc28_12.5 (%.efa) = impl_witness_access constants.%Destroy.lookup_impl_witness.1a2, element0 [symbolic = %impl.elem0.loc28_12.2 (constants.%impl.elem0.305)]
|
||||
// CHECK:STDOUT: %bound_method.loc28_12.1: <bound method> = bound_method %.loc28_12.1, %impl.elem0.loc28_12.1
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc28_12.1: <specific function> = specific_impl_function %impl.elem0.loc28_12.1, @Destroy.Op(constants.%Destroy.facet.1a6) [symbolic = %specific_impl_fn.loc28_12.2 (constants.%specific_impl_fn.52a)]
|
||||
@@ -1189,7 +1357,7 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.2b1
|
||||
// CHECK:STDOUT: %.loc17_24.3 => constants.%.1b7
|
||||
// CHECK:STDOUT: %impl.elem0.loc17_24.2 => constants.%T.as.Destroy.impl.Op.66e
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc17_24.2 => constants.%T.as.Destroy.impl.Op.specific_fn.ce9
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc17_24.2 => constants.%T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %ptr => constants.%ptr.ad9
|
||||
// CHECK:STDOUT: %require_complete.loc17_24.2 => constants.%complete_type.e23
|
||||
// CHECK:STDOUT: }
|
||||
@@ -1226,7 +1394,7 @@ fn CallIndirect() {
|
||||
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.2b1
|
||||
// CHECK:STDOUT: %.loc28_12.5 => constants.%.1b7
|
||||
// CHECK:STDOUT: %impl.elem0.loc28_12.2 => constants.%T.as.Destroy.impl.Op.66e
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc28_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn.ce9
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc28_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %ptr => constants.%ptr.ad9
|
||||
// CHECK:STDOUT: %require_complete.loc28_12.2 => constants.%complete_type.e23
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user