From d8c4fc51cddccd258d10d23a28208b70acaf2b63 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 15 Sep 2026 23:11:51 +0000 Subject: [PATCH] Fix SemIR for derived-to-base conversion and lowering crash. (#7783) We use the same conversion codepath to handle both qualification conversions and derived-to-base conversions, because we allow both to be performed at once. However, we were previously modeling the qualification conversion as happening *first*, and producing a result whose type is the target type of the overall conversion (that is, the base class type). That led to bogus SemIR, where a `Derived` -> `const Base` conversion would first have a "compatible" conversion from `Derived` to `const Base`, *then* an access of the base subobject (of type `const Base`, within an object of type `const Base`). We now reverse the order: first we do a derived-to-base conversion, which already has logic to preserve qualifiers, and then we do any necessary qualification conversions on the result to reach the overall target type. In passing, we now skip forming the `as_compatible` instruction at all for a pure derived-to-base conversion that has no qualification conversion, simplifying the SemIR by one instruction in the common case. --- toolchain/check/convert.cpp | 24 ++-- .../testdata/class/abstract/abstract.carbon | 35 +++--- .../class/access/inheritance_access.carbon | 39 +++---- .../class/field/compound_field.carbon | 24 ++-- .../class/generic/base_is_generic.carbon | 18 ++- .../class/generic/member_lookup.carbon | 23 ++-- .../class/inheritance/base_field.carbon | 9 +- .../class/inheritance/base_method.carbon | 7 +- .../inheritance/base_method_qualified.carbon | 18 ++- .../inheritance/base_method_shadow.carbon | 7 +- .../class/inheritance/derived_to_base.carbon | 104 ++++++++++-------- .../class/inheritance/import_base.carbon | 18 ++- .../class/inheritance/self_conversion.carbon | 16 ++- .../generic/template/member_access.carbon | 13 +-- .../check/testdata/impl/impl_thunk.carbon | 38 ++++--- .../interop/cpp/class/import/access.carbon | 82 ++++++-------- .../interop/cpp/class/import/base.carbon | 66 +++++------ toolchain/lower/testdata/class/convert.carbon | 93 +++++++++++----- toolchain/lower/testdata/class/virtual.carbon | 6 +- .../interop/cpp/class/import/base.carbon | 16 +-- .../interop/cpp/class/import/dynamic.carbon | 4 +- .../interop/cpp/class/import/method.carbon | 6 +- 22 files changed, 351 insertions(+), 315 deletions(-) diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 8a74cbf57b6c..171a4fb49f7d 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1409,22 +1409,28 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id, } } - value_id = AddInst( - context, loc_id, - {.type_id = target.type_id, .source_id = value_id}); + // An expression of type T converts to U if T is a class derived from U. + // First navigate to the base subobject. This preserves qualifiers. + if (inheritance_path) { + value_id = ConvertDerivedToBase(context, loc_id, value_id, + *inheritance_path); + } + // Next, switch out the qualifiers for those of the target. + if (context.insts().Get(value_id).type_id() != target.type_id) { + value_id = AddInst( + context, loc_id, + {.type_id = target.type_id, .source_id = value_id}); + } + + // Finally, add a value acquisition to get back to a value expression if + // we temporarily converted to a reference earlier. if (need_value_binding) { value_id = AddInst( context, loc_id, {.type_id = target.type_id, .value_id = value_id}); } - // An expression of type T converts to U if T is a class derived from U. - if (inheritance_path) { - value_id = ConvertDerivedToBase(context, loc_id, value_id, - *inheritance_path); - } - return value_id; } else { // TODO: Produce a custom diagnostic explaining that we can't perform diff --git a/toolchain/check/testdata/class/abstract/abstract.carbon b/toolchain/check/testdata/class/abstract/abstract.carbon index 07feff28e1bb..1481b0baf463 100644 --- a/toolchain/check/testdata/class/abstract/abstract.carbon +++ b/toolchain/check/testdata/class/abstract/abstract.carbon @@ -193,7 +193,7 @@ class Derived { fn F() { // TODO: support destroying classes that derive from abstract types. // - // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+4]]:28: error: cannot access member of interface `Core.Destroy` in type `Abstract` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: fail_todo_abstract_let_temporary.carbon:[[@LINE+4]]:28: error: cannot access member of interface `Core.Destroy` in type `Derived` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: let unused l: Abstract = {.base = {}} as Derived; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: @@ -874,12 +874,11 @@ fn Assign(ref a: Abstract) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d // CHECK:STDOUT: %a.ref: %Abstract.elem = name_ref a, @Abstract.%field_decl [concrete = @Abstract.%field_decl] -// CHECK:STDOUT: %.loc18_11.1: %Abstract = as_compatible %d.ref -// CHECK:STDOUT: %.loc18_11.2: ref %Abstract = class_element_access %.loc18_11.1, element0 -// CHECK:STDOUT: %.loc18_11.3: ref %Abstract = converted %d.ref, %.loc18_11.2 -// CHECK:STDOUT: %.loc18_11.4: ref %empty_struct_type = class_element_access %.loc18_11.3, element0 -// CHECK:STDOUT: %.loc18_11.5: init %empty_struct_type = struct_init () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc18_13: init %empty_struct_type = converted %.loc18_11.4, %.loc18_11.5 [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc18_11.1: ref %Abstract = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc18_11.2: ref %Abstract = converted %d.ref, %.loc18_11.1 +// CHECK:STDOUT: %.loc18_11.3: ref %empty_struct_type = class_element_access %.loc18_11.2, element0 +// CHECK:STDOUT: %.loc18_11.4: init %empty_struct_type = struct_init () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc18_13: init %empty_struct_type = converted %.loc18_11.3, %.loc18_11.4 [concrete = constants.%empty_struct] // CHECK:STDOUT: return %.loc18_13 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -962,11 +961,10 @@ fn Assign(ref a: Abstract) { // CHECK:STDOUT: %struct: %struct_type.base.f5e = struct_value (%empty_struct.a40) [concrete] // CHECK:STDOUT: %.79f: type = partial_type %Abstract [concrete] // CHECK:STDOUT: %empty_struct.5e0: %.79f = struct_value () [concrete] -// CHECK:STDOUT: %Abstract.val.b13: %Abstract = struct_value () [concrete] -// CHECK:STDOUT: %Derived.val: %Derived = struct_value (%Abstract.val.b13) [concrete] -// CHECK:STDOUT: %Abstract.val.1c8: %Abstract = struct_value (%Abstract.val.b13) [concrete] -// CHECK:STDOUT: %.383: ref %Abstract = temporary invalid, %Abstract.val.1c8 [concrete] -// CHECK:STDOUT: %.27a: ref %Abstract = class_element_access %.383, element0 [concrete] +// CHECK:STDOUT: %Abstract.val: %Abstract = struct_value () [concrete] +// CHECK:STDOUT: %Derived.val: %Derived = struct_value (%Abstract.val) [concrete] +// CHECK:STDOUT: %.521: ref %Derived = temporary invalid, %Derived.val [concrete] +// CHECK:STDOUT: %.5d3: ref %Abstract = class_element_access %.521, element0 [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1022,16 +1020,15 @@ fn Assign(ref a: Abstract) { // CHECK:STDOUT: %.loc17_39.3: ref %.79f = class_element_access %.loc17_39.2, element0 // CHECK:STDOUT: %.loc17_38.2: init %.79f to %.loc17_39.3 = class_init () [concrete = constants.%empty_struct.5e0] // CHECK:STDOUT: %.loc17_39.4: init %.79f = converted %.loc17_38.1, %.loc17_38.2 [concrete = constants.%empty_struct.5e0] -// CHECK:STDOUT: %.loc17_39.5: init %Abstract = as_compatible %.loc17_39.4 [concrete = constants.%Abstract.val.b13] +// CHECK:STDOUT: %.loc17_39.5: init %Abstract = as_compatible %.loc17_39.4 [concrete = constants.%Abstract.val] // CHECK:STDOUT: %.loc17_39.6: init %Derived to %.loc17_39.2 = class_init (%.loc17_39.5) [concrete = constants.%Derived.val] // CHECK:STDOUT: %.loc17_41.1: init %Derived = converted %.loc17_39.1, %.loc17_39.6 [concrete = constants.%Derived.val] -// CHECK:STDOUT: %.loc17_41.2: init %Abstract = as_compatible %.loc17_41.1 [concrete = constants.%Abstract.val.1c8] -// CHECK:STDOUT: %.loc17_41.3: ref %Abstract = temporary %.loc17_39.2, %.loc17_41.2 [concrete = constants.%.383] -// CHECK:STDOUT: %.loc17_41.4: ref %Abstract = class_element_access %.loc17_41.3, element0 [concrete = constants.%.27a] -// CHECK:STDOUT: %.loc17_41.5: ref %Abstract = converted %.loc17_41.1, %.loc17_41.4 [concrete = constants.%.27a] -// CHECK:STDOUT: %.loc17_41.6: %Abstract = acquire_value %.loc17_41.5 +// CHECK:STDOUT: %.loc17_41.2: ref %Derived = temporary %.loc17_39.2, %.loc17_41.1 [concrete = constants.%.521] +// CHECK:STDOUT: %.loc17_41.3: ref %Abstract = class_element_access %.loc17_41.2, element0 [concrete = constants.%.5d3] +// CHECK:STDOUT: %.loc17_41.4: ref %Abstract = converted %.loc17_41.1, %.loc17_41.3 [concrete = constants.%.5d3] +// CHECK:STDOUT: %.loc17_41.5: %Abstract = acquire_value %.loc17_41.4 // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] -// CHECK:STDOUT: %l: %Abstract = wrapper_binding l, %.loc17_41.6 +// CHECK:STDOUT: %l: %Abstract = wrapper_binding l, %.loc17_41.5 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %l.patt: %pattern_type.169 = value_binding_pattern l [concrete = constants.%l.patt] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/access/inheritance_access.carbon b/toolchain/check/testdata/class/access/inheritance_access.carbon index 9b99057c364e..94423d7a7c47 100644 --- a/toolchain/check/testdata/class/access/inheritance_access.carbon +++ b/toolchain/check/testdata/class/access/inheritance_access.carbon @@ -401,31 +401,29 @@ class B { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref.loc13_13: %Circle = name_ref self, %self // CHECK:STDOUT: %x.ref: %Shape.elem = name_ref x, @Shape.%field_decl.loc5 [concrete = @Shape.%field_decl.loc5] -// CHECK:STDOUT: %.loc13_17.1: %Shape = as_compatible %self.ref.loc13_13 -// CHECK:STDOUT: %.loc13_17.2: ref %Shape = class_element_access %.loc13_17.1, element0 -// CHECK:STDOUT: %.loc13_17.3: ref %Shape = converted %self.ref.loc13_13, %.loc13_17.2 -// CHECK:STDOUT: %.loc13_17.4: ref %i32 = class_element_access %.loc13_17.3, element0 +// CHECK:STDOUT: %.loc13_17.1: ref %Shape = class_element_access %self.ref.loc13_13, element0 +// CHECK:STDOUT: %.loc13_17.2: ref %Shape = converted %self.ref.loc13_13, %.loc13_17.1 +// CHECK:STDOUT: %.loc13_17.3: ref %i32 = class_element_access %.loc13_17.2, element0 // CHECK:STDOUT: %self.ref.loc13_21: %Circle = name_ref self, %self // CHECK:STDOUT: %y.ref: %Shape.elem = name_ref y, @Shape.%field_decl.loc6 [concrete = @Shape.%field_decl.loc6] -// CHECK:STDOUT: %.loc13_25.1: %Shape = as_compatible %self.ref.loc13_21 -// CHECK:STDOUT: %.loc13_25.2: ref %Shape = class_element_access %.loc13_25.1, element0 -// CHECK:STDOUT: %.loc13_25.3: ref %Shape = converted %self.ref.loc13_21, %.loc13_25.2 -// CHECK:STDOUT: %.loc13_25.4: ref %i32 = class_element_access %.loc13_25.3, element1 -// CHECK:STDOUT: %.loc13_27.1: %tuple.type.e55 = tuple_literal (%.loc13_17.4, %.loc13_25.4) -// CHECK:STDOUT: %.loc13_17.5: %i32 = acquire_value %.loc13_17.4 +// CHECK:STDOUT: %.loc13_25.1: ref %Shape = class_element_access %self.ref.loc13_21, element0 +// CHECK:STDOUT: %.loc13_25.2: ref %Shape = converted %self.ref.loc13_21, %.loc13_25.1 +// CHECK:STDOUT: %.loc13_25.3: ref %i32 = class_element_access %.loc13_25.2, element1 +// CHECK:STDOUT: %.loc13_27.1: %tuple.type.e55 = tuple_literal (%.loc13_17.3, %.loc13_25.3) +// CHECK:STDOUT: %.loc13_17.4: %i32 = acquire_value %.loc13_17.3 // CHECK:STDOUT: %impl.elem0.loc13_17: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] -// CHECK:STDOUT: %bound_method.loc13_17.1: = bound_method %.loc13_17.5, %impl.elem0.loc13_17 +// CHECK:STDOUT: %bound_method.loc13_17.1: = bound_method %.loc13_17.4, %impl.elem0.loc13_17 // CHECK:STDOUT: %specific_fn.loc13_17: = specific_function %impl.elem0.loc13_17, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc13_17.2: = bound_method %.loc13_17.5, %specific_fn.loc13_17 -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc13_17: init %i32 = call %bound_method.loc13_17.2(%.loc13_17.5) +// CHECK:STDOUT: %bound_method.loc13_17.2: = bound_method %.loc13_17.4, %specific_fn.loc13_17 +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc13_17: init %i32 = call %bound_method.loc13_17.2(%.loc13_17.4) // CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %return.param, element0 // CHECK:STDOUT: %.loc13_27.2: init %i32 to %tuple.elem0 = in_place_init %Int.as.Copy.impl.Op.call.loc13_17 -// CHECK:STDOUT: %.loc13_25.5: %i32 = acquire_value %.loc13_25.4 +// CHECK:STDOUT: %.loc13_25.4: %i32 = acquire_value %.loc13_25.3 // CHECK:STDOUT: %impl.elem0.loc13_25: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] -// CHECK:STDOUT: %bound_method.loc13_25.1: = bound_method %.loc13_25.5, %impl.elem0.loc13_25 +// CHECK:STDOUT: %bound_method.loc13_25.1: = bound_method %.loc13_25.4, %impl.elem0.loc13_25 // CHECK:STDOUT: %specific_fn.loc13_25: = specific_function %impl.elem0.loc13_25, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc13_25.2: = bound_method %.loc13_25.5, %specific_fn.loc13_25 -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc13_25: init %i32 = call %bound_method.loc13_25.2(%.loc13_25.5) +// CHECK:STDOUT: %bound_method.loc13_25.2: = bound_method %.loc13_25.4, %specific_fn.loc13_25 +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc13_25: init %i32 = call %bound_method.loc13_25.2(%.loc13_25.4) // CHECK:STDOUT: %tuple.elem1: ref %i32 = tuple_access %return.param, element1 // CHECK:STDOUT: %.loc13_27.3: init %i32 to %tuple.elem1 = in_place_init %Int.as.Copy.impl.Op.call.loc13_25 // CHECK:STDOUT: %.loc13_27.4: init %tuple.type.e55 to %return.param = tuple_init (%.loc13_27.2, %.loc13_27.3) @@ -1637,10 +1635,9 @@ class B { // CHECK:STDOUT: %self.ref: %B = name_ref self, %self // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] // CHECK:STDOUT: %x.ref: %A.elem = name_ref x, @A.%field_decl [concrete = @A.%field_decl] -// CHECK:STDOUT: %.loc12_9.1: %A = as_compatible %self.ref -// CHECK:STDOUT: %.loc12_9.2: ref %A = class_element_access %.loc12_9.1, element0 -// CHECK:STDOUT: %.loc12_9.3: ref %A = converted %self.ref, %.loc12_9.2 -// CHECK:STDOUT: %.loc12_9.4: ref %i32 = class_element_access %.loc12_9.3, element0 +// CHECK:STDOUT: %.loc12_9.1: ref %A = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc12_9.2: ref %A = converted %self.ref, %.loc12_9.1 +// CHECK:STDOUT: %.loc12_9.3: ref %i32 = class_element_access %.loc12_9.2, element0 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/field/compound_field.carbon b/toolchain/check/testdata/class/field/compound_field.carbon index c22c9a2ec56e..b29eddf01923 100644 --- a/toolchain/check/testdata/class/field/compound_field.carbon +++ b/toolchain/check/testdata/class/field/compound_field.carbon @@ -259,16 +259,15 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %b.ref: %Base.elem = name_ref b, @Base.%field_decl.loc17 [concrete = @Base.%field_decl.loc17] -// CHECK:STDOUT: %.loc33_11.1: %Base = as_compatible %d.ref -// CHECK:STDOUT: %.loc33_11.2: ref %Base = class_element_access %.loc33_11.1, element0 -// CHECK:STDOUT: %.loc33_11.3: ref %Base = converted %d.ref, %.loc33_11.2 -// CHECK:STDOUT: %.loc33_11.4: ref %i32 = class_element_access %.loc33_11.3, element1 -// CHECK:STDOUT: %.loc33_11.5: %i32 = acquire_value %.loc33_11.4 +// CHECK:STDOUT: %.loc33_11.1: ref %Base = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc33_11.2: ref %Base = converted %d.ref, %.loc33_11.1 +// CHECK:STDOUT: %.loc33_11.3: ref %i32 = class_element_access %.loc33_11.2, element1 +// CHECK:STDOUT: %.loc33_11.4: %i32 = acquire_value %.loc33_11.3 // CHECK:STDOUT: %impl.elem0: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] -// CHECK:STDOUT: %bound_method.loc33_11.1: = bound_method %.loc33_11.5, %impl.elem0 +// CHECK:STDOUT: %bound_method.loc33_11.1: = bound_method %.loc33_11.4, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc33_11.2: = bound_method %.loc33_11.5, %specific_fn -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc33_11.2(%.loc33_11.5) +// CHECK:STDOUT: %bound_method.loc33_11.2: = bound_method %.loc33_11.4, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc33_11.2(%.loc33_11.4) // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call // CHECK:STDOUT: } // CHECK:STDOUT: @@ -294,11 +293,10 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %b.ref: %Base.elem = name_ref b, @Base.%field_decl.loc17 [concrete = @Base.%field_decl.loc17] // CHECK:STDOUT: %.loc41_12.1: ref %Derived = deref %p.ref -// CHECK:STDOUT: %.loc41_12.2: ref %Base = as_compatible %.loc41_12.1 -// CHECK:STDOUT: %.loc41_12.3: ref %Base = class_element_access %.loc41_12.2, element0 -// CHECK:STDOUT: %.loc41_12.4: ref %Base = converted %.loc41_12.1, %.loc41_12.3 -// CHECK:STDOUT: %.loc41_12.5: ref %i32 = class_element_access %.loc41_12.4, element1 -// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc41_12.5 +// CHECK:STDOUT: %.loc41_12.2: ref %Base = class_element_access %.loc41_12.1, element0 +// CHECK:STDOUT: %.loc41_12.3: ref %Base = converted %.loc41_12.1, %.loc41_12.2 +// CHECK:STDOUT: %.loc41_12.4: ref %i32 = class_element_access %.loc41_12.3, element1 +// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc41_12.4 // CHECK:STDOUT: %impl.elem0: %.6d0 = impl_witness_access constants.%Copy.impl_witness.5df, element0 [concrete = constants.%ptr.as.Copy.impl.Op.d1c] // CHECK:STDOUT: %bound_method.loc41_10.1: = bound_method %addr, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%i32) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn] diff --git a/toolchain/check/testdata/class/generic/base_is_generic.carbon b/toolchain/check/testdata/class/generic/base_is_generic.carbon index ac2865e25157..29d6b95793f7 100644 --- a/toolchain/check/testdata/class/generic/base_is_generic.carbon +++ b/toolchain/check/testdata/class/generic/base_is_generic.carbon @@ -249,12 +249,11 @@ fn H() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d // CHECK:STDOUT: %x.ref: %Base.elem.3f2 = name_ref x, @Base.%field_decl [concrete = @Base.%field_decl] -// CHECK:STDOUT: %.loc17_11.1: %Base.947 = as_compatible %d.ref -// CHECK:STDOUT: %.loc17_11.2: ref %Base.947 = class_element_access %.loc17_11.1, element0 -// CHECK:STDOUT: %.loc17_11.3: ref %Base.947 = converted %d.ref, %.loc17_11.2 -// CHECK:STDOUT: %.loc17_11.4: ref %Param = class_element_access %.loc17_11.3, element0 +// CHECK:STDOUT: %.loc17_11.1: ref %Base.947 = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc17_11.2: ref %Base.947 = converted %d.ref, %.loc17_11.1 +// CHECK:STDOUT: %.loc17_11.3: ref %Param = class_element_access %.loc17_11.2, element0 // CHECK:STDOUT: %y.ref: %Param.elem = name_ref y, @Param.%field_decl [concrete = @Param.%field_decl] -// CHECK:STDOUT: %.loc17_13.1: ref %i32 = class_element_access %.loc17_11.4, element0 +// CHECK:STDOUT: %.loc17_13.1: ref %i32 = class_element_access %.loc17_11.3, element0 // CHECK:STDOUT: %.loc17_13.2: %i32 = acquire_value %.loc17_13.1 // CHECK:STDOUT: %impl.elem0: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] // CHECK:STDOUT: %bound_method.loc17_13.1: = bound_method %.loc17_13.2, %impl.elem0 @@ -430,12 +429,11 @@ fn H() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d // CHECK:STDOUT: %x.ref: %Base.elem.3f2 = name_ref x, imports.%Main.import_ref.be5 [concrete = imports.%field_decl.2df] -// CHECK:STDOUT: %.loc7_11.1: %Base.947 = as_compatible %d.ref -// CHECK:STDOUT: %.loc7_11.2: ref %Base.947 = class_element_access %.loc7_11.1, element0 -// CHECK:STDOUT: %.loc7_11.3: ref %Base.947 = converted %d.ref, %.loc7_11.2 -// CHECK:STDOUT: %.loc7_11.4: ref %Param = class_element_access %.loc7_11.3, element0 +// CHECK:STDOUT: %.loc7_11.1: ref %Base.947 = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc7_11.2: ref %Base.947 = converted %d.ref, %.loc7_11.1 +// CHECK:STDOUT: %.loc7_11.3: ref %Param = class_element_access %.loc7_11.2, element0 // CHECK:STDOUT: %y.ref: %Param.elem = name_ref y, imports.%Main.import_ref.a22 [concrete = imports.%field_decl.864] -// CHECK:STDOUT: %.loc7_13.1: ref %i32 = class_element_access %.loc7_11.4, element0 +// CHECK:STDOUT: %.loc7_13.1: ref %i32 = class_element_access %.loc7_11.3, element0 // CHECK:STDOUT: %.loc7_13.2: %i32 = acquire_value %.loc7_13.1 // CHECK:STDOUT: %impl.elem0: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] // CHECK:STDOUT: %bound_method.loc7_13.1: = bound_method %.loc7_13.2, %impl.elem0 diff --git a/toolchain/check/testdata/class/generic/member_lookup.carbon b/toolchain/check/testdata/class/generic/member_lookup.carbon index 35586134628a..3323f4aae233 100644 --- a/toolchain/check/testdata/class/generic/member_lookup.carbon +++ b/toolchain/check/testdata/class/generic/member_lookup.carbon @@ -146,28 +146,27 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %require_complete.loc21_11: = require_complete_type %Base [symbolic = %require_complete.loc21_11 (constants.%require_complete.0fb)] // CHECK:STDOUT: %require_complete.loc21_13: = require_complete_type %T.as_type.loc19_41.1 [symbolic = %require_complete.loc21_13 (constants.%require_complete.d83)] // CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%T.loc19_16.1) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.c85f21.2)] -// CHECK:STDOUT: %.loc21_11.8: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %T.loc19_16.1 [symbolic = %.loc21_11.8 (constants.%.c29)] +// CHECK:STDOUT: %.loc21_11.7: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %T.loc19_16.1 [symbolic = %.loc21_11.7 (constants.%.c29)] // CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %T.loc19_16.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.d9c)] -// CHECK:STDOUT: %impl.elem0.loc21_11.2: @AccessBase.%.loc21_11.8 (%.c29) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.bd2)] +// CHECK:STDOUT: %impl.elem0.loc21_11.2: @AccessBase.%.loc21_11.7 (%.c29) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.bd2)] // CHECK:STDOUT: %specific_impl_fn.loc21_11.2: = specific_impl_function %impl.elem0.loc21_11.2, @Copy.WithSelf.Op(%T.loc19_16.1) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.e2a)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%x.param: @AccessBase.%Derived.loc19_41.1 (%Derived.e87)) -> out %return.param: @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @AccessBase.%Derived.loc19_41.1 (%Derived.e87) = name_ref x, %x // CHECK:STDOUT: %b.ref: @AccessBase.%Base.elem (%Base.elem.209) = name_ref b, @Base.%field_decl [concrete = @Base.%field_decl] -// CHECK:STDOUT: %.loc21_11.1: @AccessBase.%Base (%Base.146) = as_compatible %x.ref -// CHECK:STDOUT: %.loc21_11.2: ref @AccessBase.%Base (%Base.146) = class_element_access %.loc21_11.1, element0 -// CHECK:STDOUT: %.loc21_11.3: ref @AccessBase.%Base (%Base.146) = converted %x.ref, %.loc21_11.2 -// CHECK:STDOUT: %.loc21_11.4: ref @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) = class_element_access %.loc21_11.3, element0 -// CHECK:STDOUT: %.loc21_11.5: @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) = acquire_value %.loc21_11.4 -// CHECK:STDOUT: %impl.elem0.loc21_11.1: @AccessBase.%.loc21_11.8 (%.c29) = impl_witness_access constants.%Copy.lookup_impl_witness.d9c, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.bd2)] -// CHECK:STDOUT: %bound_method.loc21_11.1: = bound_method %.loc21_11.5, %impl.elem0.loc21_11.1 +// CHECK:STDOUT: %.loc21_11.1: ref @AccessBase.%Base (%Base.146) = class_element_access %x.ref, element0 +// CHECK:STDOUT: %.loc21_11.2: ref @AccessBase.%Base (%Base.146) = converted %x.ref, %.loc21_11.1 +// CHECK:STDOUT: %.loc21_11.3: ref @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) = class_element_access %.loc21_11.2, element0 +// CHECK:STDOUT: %.loc21_11.4: @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) = acquire_value %.loc21_11.3 +// CHECK:STDOUT: %impl.elem0.loc21_11.1: @AccessBase.%.loc21_11.7 (%.c29) = impl_witness_access constants.%Copy.lookup_impl_witness.d9c, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.bd2)] +// CHECK:STDOUT: %bound_method.loc21_11.1: = bound_method %.loc21_11.4, %impl.elem0.loc21_11.1 +// CHECK:STDOUT: %.loc21_11.5: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc19_16.1 (constants.%T.f84)] // CHECK:STDOUT: %.loc21_11.6: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc19_16.1 (constants.%T.f84)] -// CHECK:STDOUT: %.loc21_11.7: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc19_16.1 (constants.%T.f84)] // CHECK:STDOUT: %specific_impl_fn.loc21_11.1: = specific_impl_function %impl.elem0.loc21_11.1, @Copy.WithSelf.Op(constants.%T.f84) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.e2a)] -// CHECK:STDOUT: %bound_method.loc21_11.2: = bound_method %.loc21_11.5, %specific_impl_fn.loc21_11.1 +// CHECK:STDOUT: %bound_method.loc21_11.2: = bound_method %.loc21_11.4, %specific_impl_fn.loc21_11.1 // CHECK:STDOUT: -// CHECK:STDOUT: %Copy.WithSelf.Op.call: init @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) to %.loc19_47.1 = call %bound_method.loc21_11.2(%.loc21_11.5) +// CHECK:STDOUT: %Copy.WithSelf.Op.call: init @AccessBase.%T.as_type.loc19_41.1 (%T.as_type) to %.loc19_47.1 = call %bound_method.loc21_11.2(%.loc21_11.4) // CHECK:STDOUT: return %Copy.WithSelf.Op.call to %return.param // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/inheritance/base_field.carbon b/toolchain/check/testdata/class/inheritance/base_field.carbon index 6ab6f6ac8fb0..62b771be91c7 100644 --- a/toolchain/check/testdata/class/inheritance/base_field.carbon +++ b/toolchain/check/testdata/class/inheritance/base_field.carbon @@ -159,11 +159,10 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: %p.ref: %ptr.64c = name_ref p, %p // CHECK:STDOUT: %.loc29_12: ref %Derived = deref %p.ref // CHECK:STDOUT: %c.ref: %Base.elem = name_ref c, @Base.%field_decl.loc18 [concrete = @Base.%field_decl.loc18] -// CHECK:STDOUT: %.loc29_15.1: ref %Base = as_compatible %.loc29_12 -// CHECK:STDOUT: %.loc29_15.2: ref %Base = class_element_access %.loc29_15.1, element0 -// CHECK:STDOUT: %.loc29_15.3: ref %Base = converted %.loc29_12, %.loc29_15.2 -// CHECK:STDOUT: %.loc29_15.4: ref %i32 = class_element_access %.loc29_15.3, element2 -// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc29_15.4 +// CHECK:STDOUT: %.loc29_15.1: ref %Base = class_element_access %.loc29_12, element0 +// CHECK:STDOUT: %.loc29_15.2: ref %Base = converted %.loc29_12, %.loc29_15.1 +// CHECK:STDOUT: %.loc29_15.3: ref %i32 = class_element_access %.loc29_15.2, element2 +// CHECK:STDOUT: %addr: %ptr.d08 = addr_of %.loc29_15.3 // CHECK:STDOUT: %impl.elem0: %.6d0 = impl_witness_access constants.%Copy.impl_witness.5df, element0 [concrete = constants.%ptr.as.Copy.impl.Op.d1c] // CHECK:STDOUT: %bound_method.loc29_10.1: = bound_method %addr, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%i32) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn] diff --git a/toolchain/check/testdata/class/inheritance/base_method.carbon b/toolchain/check/testdata/class/inheritance/base_method.carbon index bacf0f7eac43..f06f372961ad 100644 --- a/toolchain/check/testdata/class/inheritance/base_method.carbon +++ b/toolchain/check/testdata/class/inheritance/base_method.carbon @@ -177,10 +177,9 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %.loc30_4.1: ref %Derived = deref %p.ref // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] // CHECK:STDOUT: %Base.F.bound: = bound_method %.loc30_4.1, %F.ref -// CHECK:STDOUT: %.loc30_4.2: ref %Base = as_compatible %.loc30_4.1 -// CHECK:STDOUT: %.loc30_4.3: ref %Base = class_element_access %.loc30_4.2, element0 -// CHECK:STDOUT: %.loc30_4.4: ref %Base = converted %.loc30_4.1, %.loc30_4.3 -// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc30_4.4) +// CHECK:STDOUT: %.loc30_4.2: ref %Base = class_element_access %.loc30_4.1, element0 +// CHECK:STDOUT: %.loc30_4.3: ref %Base = converted %.loc30_4.1, %.loc30_4.2 +// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc30_4.3) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/inheritance/base_method_qualified.carbon b/toolchain/check/testdata/class/inheritance/base_method_qualified.carbon index a615e3d7f8b5..3d5952a8ddfa 100644 --- a/toolchain/check/testdata/class/inheritance/base_method_qualified.carbon +++ b/toolchain/check/testdata/class/inheritance/base_method_qualified.carbon @@ -261,11 +261,10 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] // CHECK:STDOUT: %Base.F.bound: = bound_method %a.ref, %F.ref -// CHECK:STDOUT: %.loc30_10.1: %Base = as_compatible %a.ref -// CHECK:STDOUT: %.loc30_10.2: ref %Base = class_element_access %.loc30_10.1, element0 -// CHECK:STDOUT: %.loc30_10.3: ref %Base = converted %a.ref, %.loc30_10.2 -// CHECK:STDOUT: %.loc30_10.4: %Base = acquire_value %.loc30_10.3 -// CHECK:STDOUT: %Base.F.call: init %i32 = call %Base.F.bound(%.loc30_10.4) +// CHECK:STDOUT: %.loc30_10.1: ref %Base = class_element_access %a.ref, element0 +// CHECK:STDOUT: %.loc30_10.2: ref %Base = converted %a.ref, %.loc30_10.1 +// CHECK:STDOUT: %.loc30_10.3: %Base = acquire_value %.loc30_10.2 +// CHECK:STDOUT: %Base.F.call: init %i32 = call %Base.F.bound(%.loc30_10.3) // CHECK:STDOUT: return %Base.F.call // CHECK:STDOUT: } // CHECK:STDOUT: @@ -276,11 +275,10 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] // CHECK:STDOUT: %.loc34_11.1: ref %Derived = deref %p.ref // CHECK:STDOUT: %Base.F.bound: = bound_method %.loc34_11.1, %F.ref -// CHECK:STDOUT: %.loc34_11.2: ref %Base = as_compatible %.loc34_11.1 -// CHECK:STDOUT: %.loc34_11.3: ref %Base = class_element_access %.loc34_11.2, element0 -// CHECK:STDOUT: %.loc34_11.4: ref %Base = converted %.loc34_11.1, %.loc34_11.3 -// CHECK:STDOUT: %.loc34_11.5: %Base = acquire_value %.loc34_11.4 -// CHECK:STDOUT: %Base.F.call: init %i32 = call %Base.F.bound(%.loc34_11.5) +// CHECK:STDOUT: %.loc34_11.2: ref %Base = class_element_access %.loc34_11.1, element0 +// CHECK:STDOUT: %.loc34_11.3: ref %Base = converted %.loc34_11.1, %.loc34_11.2 +// CHECK:STDOUT: %.loc34_11.4: %Base = acquire_value %.loc34_11.3 +// CHECK:STDOUT: %Base.F.call: init %i32 = call %Base.F.bound(%.loc34_11.4) // CHECK:STDOUT: return %Base.F.call // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/inheritance/base_method_shadow.carbon b/toolchain/check/testdata/class/inheritance/base_method_shadow.carbon index 2637b98e996a..0466d1bdcfcc 100644 --- a/toolchain/check/testdata/class/inheritance/base_method_shadow.carbon +++ b/toolchain/check/testdata/class/inheritance/base_method_shadow.carbon @@ -249,10 +249,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %.loc37_4.1: ref %D = deref %d.ref // CHECK:STDOUT: %F.ref.loc37: %B.F.type = name_ref F, @B.%B.F.decl [concrete = constants.%B.F] // CHECK:STDOUT: %B.F.bound.loc37: = bound_method %.loc37_4.1, %F.ref.loc37 -// CHECK:STDOUT: %.loc37_4.2: ref %B = as_compatible %.loc37_4.1 -// CHECK:STDOUT: %.loc37_4.3: ref %B = class_element_access %.loc37_4.2, element0 -// CHECK:STDOUT: %.loc37_4.4: ref %B = converted %.loc37_4.1, %.loc37_4.3 -// CHECK:STDOUT: %B.F.call.loc37: init %empty_tuple.type = call %B.F.bound.loc37(%.loc37_4.4) +// CHECK:STDOUT: %.loc37_4.2: ref %B = class_element_access %.loc37_4.1, element0 +// CHECK:STDOUT: %.loc37_4.3: ref %B = converted %.loc37_4.1, %.loc37_4.2 +// CHECK:STDOUT: %B.F.call.loc37: init %empty_tuple.type = call %B.F.bound.loc37(%.loc37_4.3) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/inheritance/derived_to_base.carbon b/toolchain/check/testdata/class/inheritance/derived_to_base.carbon index ca955da76ee1..e1afd600e2e0 100644 --- a/toolchain/check/testdata/class/inheritance/derived_to_base.carbon +++ b/toolchain/check/testdata/class/inheritance/derived_to_base.carbon @@ -131,7 +131,9 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %struct_type.a.a92: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %struct_type.base.b.6c4: type = struct_type {.base: %A, .b: %i32} [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %struct_type.base.c.faf: type = struct_type {.base: %B, .c: %i32} [concrete] // CHECK:STDOUT: %ptr.6b6: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.fcb: type = pattern_type %ptr.6b6 [concrete] // CHECK:STDOUT: %p.param_patt.9b8: %pattern_type.fcb = value_param_pattern [concrete] @@ -212,23 +214,22 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: %bound_method.953: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.0c6: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %struct.7e2: %.3d6 = struct_value (%int_1.0c6) [concrete] -// CHECK:STDOUT: %A.val.f6a: %A = struct_value (%int_1.0c6) [concrete] +// CHECK:STDOUT: %A.val: %A = struct_value (%int_1.0c6) [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete] // CHECK:STDOUT: %bound_method.3cb: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_2.295: %i32 = int_value 2 [concrete] -// CHECK:STDOUT: %struct.a8a: %.640 = struct_value (%A.val.f6a, %int_2.295) [concrete] -// CHECK:STDOUT: %B.val: %B = struct_value (%A.val.f6a, %int_2.295) [concrete] +// CHECK:STDOUT: %struct.a8a: %.640 = struct_value (%A.val, %int_2.295) [concrete] +// CHECK:STDOUT: %B.val: %B = struct_value (%A.val, %int_2.295) [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.485: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete] // CHECK:STDOUT: %bound_method.763: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_3.410: %i32 = int_value 3 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value (%B.val, %int_3.410) [concrete] -// CHECK:STDOUT: %A.val.985: %A = struct_value (%B.val, %int_3.410) [concrete] -// CHECK:STDOUT: %.320: ref %A = temporary invalid, %A.val.985 [concrete] -// CHECK:STDOUT: %.38f: ref %B = class_element_access %.320, element0 [concrete] -// CHECK:STDOUT: %.79d: ref %A = class_element_access %.38f, element0 [concrete] -// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.4: type = fn_type @Destroy.WithSelf.Op.loc32_66.4 [concrete] -// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.4: %Destroy.WithSelf.Op.type.ef016f.4 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: = bound_method %.320, %Destroy.WithSelf.Op.403171.4 [concrete] +// CHECK:STDOUT: %.084: ref %C = temporary invalid, %C.val [concrete] +// CHECK:STDOUT: %.107: ref %B = class_element_access %.084, element0 [concrete] +// CHECK:STDOUT: %.5ce: ref %A = class_element_access %.107, element0 [concrete] +// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.8: type = fn_type @Destroy.WithSelf.Op.loc32_66.8 [concrete] +// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.8: %Destroy.WithSelf.Op.type.ef016f.8 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: = bound_method %.084, %Destroy.WithSelf.Op.403171.8 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -371,13 +372,12 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: fn @ConvertValue(%c.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %C = name_ref c, %c -// CHECK:STDOUT: %.loc24_21.1: %A = as_compatible %c.ref -// CHECK:STDOUT: %.loc24_21.2: ref %B = class_element_access %.loc24_21.1, element0 -// CHECK:STDOUT: %.loc24_21.3: ref %A = class_element_access %.loc24_21.2, element0 -// CHECK:STDOUT: %.loc24_21.4: ref %A = converted %c.ref, %.loc24_21.3 -// CHECK:STDOUT: %.loc24_21.5: %A = acquire_value %.loc24_21.4 +// CHECK:STDOUT: %.loc24_21.1: ref %B = class_element_access %c.ref, element0 +// CHECK:STDOUT: %.loc24_21.2: ref %A = class_element_access %.loc24_21.1, element0 +// CHECK:STDOUT: %.loc24_21.3: ref %A = converted %c.ref, %.loc24_21.2 +// CHECK:STDOUT: %.loc24_21.4: %A = acquire_value %.loc24_21.3 // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] -// CHECK:STDOUT: %a: %A = wrapper_binding a, %.loc24_21.5 +// CHECK:STDOUT: %a: %A = wrapper_binding a, %.loc24_21.4 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %a.patt: %pattern_type.9ef = value_binding_pattern a [concrete = constants.%a.patt.bb7b23.1] // CHECK:STDOUT: } @@ -389,11 +389,10 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: %c.ref: %ptr.6b6 = name_ref c, %c // CHECK:STDOUT: %.loc28_12: ref %C = deref %c.ref // CHECK:STDOUT: %A.ref.loc28: type = name_ref A, file.%A.decl [concrete = constants.%A] -// CHECK:STDOUT: %.loc28_15.1: ref %A = as_compatible %.loc28_12 -// CHECK:STDOUT: %.loc28_15.2: ref %B = class_element_access %.loc28_15.1, element0 -// CHECK:STDOUT: %.loc28_15.3: ref %A = class_element_access %.loc28_15.2, element0 -// CHECK:STDOUT: %.loc28_15.4: ref %A = converted %.loc28_12, %.loc28_15.3 -// CHECK:STDOUT: %addr: %ptr.d43 = addr_of %.loc28_15.4 +// CHECK:STDOUT: %.loc28_15.1: ref %B = class_element_access %.loc28_12, element0 +// CHECK:STDOUT: %.loc28_15.2: ref %A = class_element_access %.loc28_15.1, element0 +// CHECK:STDOUT: %.loc28_15.3: ref %A = converted %.loc28_12, %.loc28_15.2 +// CHECK:STDOUT: %addr: %ptr.d43 = addr_of %.loc28_15.3 // CHECK:STDOUT: %impl.elem0: %.54e = impl_witness_access constants.%Copy.impl_witness.8be, element0 [concrete = constants.%ptr.as.Copy.impl.Op.5a8] // CHECK:STDOUT: %bound_method.loc28_10.1: = bound_method %addr, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%A) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn.d1a] @@ -424,7 +423,7 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: %.loc32_46.4: init %i32 to %.loc32_46.3 = in_place_init %.loc32_46.2 [concrete = constants.%int_1.0c6] // CHECK:STDOUT: %.loc32_46.5: init %.3d6 to %.loc32_55.2 = class_init (%.loc32_46.4) [concrete = constants.%struct.7e2] // CHECK:STDOUT: %.loc32_55.3: init %.3d6 = converted %.loc32_46.1, %.loc32_46.5 [concrete = constants.%struct.7e2] -// CHECK:STDOUT: %.loc32_55.4: init %A = as_compatible %.loc32_55.3 [concrete = constants.%A.val.f6a] +// CHECK:STDOUT: %.loc32_55.4: init %A = as_compatible %.loc32_55.3 [concrete = constants.%A.val] // CHECK:STDOUT: %impl.elem0.loc32_55: %.b7a = impl_witness_access constants.%ImplicitAs.impl_witness.a2a, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39] // CHECK:STDOUT: %bound_method.loc32_55.1: = bound_method %int_2, %impl.elem0.loc32_55 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3] // CHECK:STDOUT: %specific_fn.loc32_55: = specific_function %impl.elem0.loc32_55, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] @@ -446,18 +445,17 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: %.loc32_64.8: init %i32 to %.loc32_64.7 = in_place_init %.loc32_64.6 [concrete = constants.%int_3.410] // CHECK:STDOUT: %.loc32_64.9: init %C to %.loc32_64.2 = class_init (%.loc32_64.5, %.loc32_64.8) [concrete = constants.%C.val] // CHECK:STDOUT: %.loc32_66.1: init %C = converted %.loc32_64.1, %.loc32_64.9 [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc32_66.2: init %A = as_compatible %.loc32_66.1 [concrete = constants.%A.val.985] -// CHECK:STDOUT: %.loc32_66.3: ref %A = temporary %.loc32_64.2, %.loc32_66.2 [concrete = constants.%.320] -// CHECK:STDOUT: %.loc32_66.4: ref %B = class_element_access %.loc32_66.3, element0 [concrete = constants.%.38f] -// CHECK:STDOUT: %.loc32_66.5: ref %A = class_element_access %.loc32_66.4, element0 [concrete = constants.%.79d] -// CHECK:STDOUT: %.loc32_66.6: ref %A = converted %.loc32_66.1, %.loc32_66.5 [concrete = constants.%.79d] -// CHECK:STDOUT: %.loc32_66.7: %A = acquire_value %.loc32_66.6 +// CHECK:STDOUT: %.loc32_66.2: ref %C = temporary %.loc32_64.2, %.loc32_66.1 [concrete = constants.%.084] +// CHECK:STDOUT: %.loc32_66.3: ref %B = class_element_access %.loc32_66.2, element0 [concrete = constants.%.107] +// CHECK:STDOUT: %.loc32_66.4: ref %A = class_element_access %.loc32_66.3, element0 [concrete = constants.%.5ce] +// CHECK:STDOUT: %.loc32_66.5: ref %A = converted %.loc32_66.1, %.loc32_66.4 [concrete = constants.%.5ce] +// CHECK:STDOUT: %.loc32_66.6: %A = acquire_value %.loc32_66.5 // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] -// CHECK:STDOUT: %a: %A = wrapper_binding a, %.loc32_66.7 +// CHECK:STDOUT: %a: %A = wrapper_binding a, %.loc32_66.6 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %a.patt: %pattern_type.9ef = value_binding_pattern a [concrete = constants.%a.patt.bb7b23.2] // CHECK:STDOUT: } -// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.320) +// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.084) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -478,6 +476,26 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc32_66.5(%self.param: ref %struct_type.base.b.6c4) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc32_66.6(%self.param: ref %B) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc32_66.7(%self.param: ref %struct_type.base.c.faf) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc32_66.8(%self.param: ref %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- qualified.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -534,8 +552,8 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %TakeConstA.ref: %TakeConstA.type = name_ref TakeConstA, file.%TakeConstA.decl [concrete = constants.%TakeConstA] // CHECK:STDOUT: %p.ref: %B = name_ref p, %p -// CHECK:STDOUT: %.loc15_14.1: %const.b97 = as_compatible %p.ref -// CHECK:STDOUT: %.loc15_14.2: ref %const.b97 = class_element_access %.loc15_14.1, element0 +// CHECK:STDOUT: %.loc15_14.1: ref %A = class_element_access %p.ref, element0 +// CHECK:STDOUT: %.loc15_14.2: ref %const.b97 = as_compatible %.loc15_14.1 // CHECK:STDOUT: %.loc15_14.3: ref %const.b97 = converted %p.ref, %.loc15_14.2 // CHECK:STDOUT: %.loc15_14.4: %const.b97 = acquire_value %.loc15_14.3 // CHECK:STDOUT: %TakeConstA.call: init %empty_tuple.type = call %TakeConstA.ref(%.loc15_14.4) @@ -546,11 +564,10 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %TakeConstA.ref: %TakeConstA.type = name_ref TakeConstA, file.%TakeConstA.decl [concrete = constants.%TakeConstA] // CHECK:STDOUT: %p.ref: %const.825 = name_ref p, %p -// CHECK:STDOUT: %.loc21_14.1: %const.b97 = as_compatible %p.ref -// CHECK:STDOUT: %.loc21_14.2: ref %const.b97 = class_element_access %.loc21_14.1, element0 -// CHECK:STDOUT: %.loc21_14.3: ref %const.b97 = converted %p.ref, %.loc21_14.2 -// CHECK:STDOUT: %.loc21_14.4: %const.b97 = acquire_value %.loc21_14.3 -// CHECK:STDOUT: %TakeConstA.call: init %empty_tuple.type = call %TakeConstA.ref(%.loc21_14.4) +// CHECK:STDOUT: %.loc21_14.1: ref %const.b97 = class_element_access %p.ref, element0 +// CHECK:STDOUT: %.loc21_14.2: ref %const.b97 = converted %p.ref, %.loc21_14.1 +// CHECK:STDOUT: %.loc21_14.3: %const.b97 = acquire_value %.loc21_14.2 +// CHECK:STDOUT: %TakeConstA.call: init %empty_tuple.type = call %TakeConstA.ref(%.loc21_14.3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -570,8 +587,8 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %TakePartialA.ref: %TakePartialA.type = name_ref TakePartialA, file.%TakePartialA.decl [concrete = constants.%TakePartialA] // CHECK:STDOUT: %b.ref: %B = name_ref b, %b -// CHECK:STDOUT: %.loc15_16.1: %.3d6 = as_compatible %b.ref -// CHECK:STDOUT: %.loc15_16.2: ref %.3d6 = class_element_access %.loc15_16.1, element0 +// CHECK:STDOUT: %.loc15_16.1: ref %A = class_element_access %b.ref, element0 +// CHECK:STDOUT: %.loc15_16.2: ref %.3d6 = as_compatible %.loc15_16.1 // CHECK:STDOUT: %.loc15_16.3: ref %.3d6 = converted %b.ref, %.loc15_16.2 // CHECK:STDOUT: %.loc15_16.4: %.3d6 = acquire_value %.loc15_16.3 // CHECK:STDOUT: %TakePartialA.call: init %empty_tuple.type = call %TakePartialA.ref(%.loc15_16.4) @@ -582,11 +599,10 @@ fn PassPartialB(b: partial B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %TakePartialA.ref: %TakePartialA.type = name_ref TakePartialA, file.%TakePartialA.decl [concrete = constants.%TakePartialA] // CHECK:STDOUT: %b.ref: %.640 = name_ref b, %b -// CHECK:STDOUT: %.loc21_16.1: %.3d6 = as_compatible %b.ref -// CHECK:STDOUT: %.loc21_16.2: ref %.3d6 = class_element_access %.loc21_16.1, element0 -// CHECK:STDOUT: %.loc21_16.3: ref %.3d6 = converted %b.ref, %.loc21_16.2 -// CHECK:STDOUT: %.loc21_16.4: %.3d6 = acquire_value %.loc21_16.3 -// CHECK:STDOUT: %TakePartialA.call: init %empty_tuple.type = call %TakePartialA.ref(%.loc21_16.4) +// CHECK:STDOUT: %.loc21_16.1: ref %.3d6 = class_element_access %b.ref, element0 +// CHECK:STDOUT: %.loc21_16.2: ref %.3d6 = converted %b.ref, %.loc21_16.1 +// CHECK:STDOUT: %.loc21_16.3: %.3d6 = acquire_value %.loc21_16.2 +// CHECK:STDOUT: %TakePartialA.call: init %empty_tuple.type = call %TakePartialA.ref(%.loc21_16.3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/inheritance/import_base.carbon b/toolchain/check/testdata/class/inheritance/import_base.carbon index 2d20f5ce6ac0..d044177a2fe4 100644 --- a/toolchain/check/testdata/class/inheritance/import_base.carbon +++ b/toolchain/check/testdata/class/inheritance/import_base.carbon @@ -294,10 +294,9 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: %a.ref.loc8: ref %Child = name_ref a, %a // CHECK:STDOUT: %x.ref: %Base.elem = name_ref x, imports.%Main.import_ref.dea [concrete = imports.%field_decl] -// CHECK:STDOUT: %.loc8_4.1: ref %Base = as_compatible %a.ref.loc8 -// CHECK:STDOUT: %.loc8_4.2: ref %Base = class_element_access %.loc8_4.1, element0 -// CHECK:STDOUT: %.loc8_4.3: ref %Base = converted %a.ref.loc8, %.loc8_4.2 -// CHECK:STDOUT: %.loc8_4.4: ref %i32 = class_element_access %.loc8_4.3, element0 +// CHECK:STDOUT: %.loc8_4.1: ref %Base = class_element_access %a.ref.loc8, element0 +// CHECK:STDOUT: %.loc8_4.2: ref %Base = converted %a.ref.loc8, %.loc8_4.1 +// CHECK:STDOUT: %.loc8_4.3: ref %i32 = class_element_access %.loc8_4.2, element0 // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] // CHECK:STDOUT: %impl.elem0.loc8: %.b7a = impl_witness_access constants.%ImplicitAs.impl_witness.a2a, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39] // CHECK:STDOUT: %bound_method.loc8_7.1: = bound_method %int_2, %impl.elem0.loc8 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3] @@ -305,15 +304,14 @@ fn Run() { // CHECK:STDOUT: %bound_method.loc8_7.2: = bound_method %int_2, %specific_fn.loc8 [concrete = constants.%bound_method.3cb] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %i32 = call %bound_method.loc8_7.2(%int_2) [concrete = constants.%int_2.295] // CHECK:STDOUT: %.loc8_7: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%int_2.295] -// CHECK:STDOUT: assign %.loc8_4.4, %.loc8_7 +// CHECK:STDOUT: assign %.loc8_4.3, %.loc8_7 // CHECK:STDOUT: %a.ref.loc9: ref %Child = name_ref a, %a // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, imports.%Main.import_ref.bc9 [concrete = constants.%Base.F] // CHECK:STDOUT: %Base.F.bound: = bound_method %a.ref.loc9, %F.ref -// CHECK:STDOUT: %.loc9_3.1: ref %Base = as_compatible %a.ref.loc9 -// CHECK:STDOUT: %.loc9_3.2: ref %Base = class_element_access %.loc9_3.1, element0 -// CHECK:STDOUT: %.loc9_3.3: ref %Base = converted %a.ref.loc9, %.loc9_3.2 -// CHECK:STDOUT: %.loc9_3.4: %Base = acquire_value %.loc9_3.3 -// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc9_3.4) +// CHECK:STDOUT: %.loc9_3.1: ref %Base = class_element_access %a.ref.loc9, element0 +// CHECK:STDOUT: %.loc9_3.2: ref %Base = converted %a.ref.loc9, %.loc9_3.1 +// CHECK:STDOUT: %.loc9_3.3: %Base = acquire_value %.loc9_3.2 +// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc9_3.3) // CHECK:STDOUT: %Destroy.WithSelf.Op.bound: = bound_method %a.var, constants.%Destroy.WithSelf.Op.403171.6 // CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%a.var) // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/class/inheritance/self_conversion.carbon b/toolchain/check/testdata/class/inheritance/self_conversion.carbon index e71f6bb039c5..817859f3a6d5 100644 --- a/toolchain/check/testdata/class/inheritance/self_conversion.carbon +++ b/toolchain/check/testdata/class/inheritance/self_conversion.carbon @@ -255,19 +255,17 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %.loc35_4.1: ref %Derived = deref %p.ref.loc35 // CHECK:STDOUT: %RefSelfBase.ref: %Derived.RefSelfBase.type = name_ref RefSelfBase, @Derived.%Derived.RefSelfBase.decl [concrete = constants.%Derived.RefSelfBase] // CHECK:STDOUT: %Derived.RefSelfBase.bound: = bound_method %.loc35_4.1, %RefSelfBase.ref -// CHECK:STDOUT: %.loc35_4.2: ref %Base = as_compatible %.loc35_4.1 -// CHECK:STDOUT: %.loc35_4.3: ref %Base = class_element_access %.loc35_4.2, element0 -// CHECK:STDOUT: %.loc35_4.4: ref %Base = converted %.loc35_4.1, %.loc35_4.3 -// CHECK:STDOUT: %Derived.RefSelfBase.call: init %empty_tuple.type = call %Derived.RefSelfBase.bound(%.loc35_4.4) +// CHECK:STDOUT: %.loc35_4.2: ref %Base = class_element_access %.loc35_4.1, element0 +// CHECK:STDOUT: %.loc35_4.3: ref %Base = converted %.loc35_4.1, %.loc35_4.2 +// CHECK:STDOUT: %Derived.RefSelfBase.call: init %empty_tuple.type = call %Derived.RefSelfBase.bound(%.loc35_4.3) // CHECK:STDOUT: %p.ref.loc36: %ptr.64c = name_ref p, %p // CHECK:STDOUT: %.loc36_11.1: ref %Derived = deref %p.ref.loc36 // CHECK:STDOUT: %SelfBase.ref: %Derived.SelfBase.type = name_ref SelfBase, @Derived.%Derived.SelfBase.decl [concrete = constants.%Derived.SelfBase] // CHECK:STDOUT: %Derived.SelfBase.bound: = bound_method %.loc36_11.1, %SelfBase.ref -// CHECK:STDOUT: %.loc36_11.2: ref %Base = as_compatible %.loc36_11.1 -// CHECK:STDOUT: %.loc36_11.3: ref %Base = class_element_access %.loc36_11.2, element0 -// CHECK:STDOUT: %.loc36_11.4: ref %Base = converted %.loc36_11.1, %.loc36_11.3 -// CHECK:STDOUT: %.loc36_11.5: %Base = acquire_value %.loc36_11.4 -// CHECK:STDOUT: %Derived.SelfBase.call: init %i32 = call %Derived.SelfBase.bound(%.loc36_11.5) +// CHECK:STDOUT: %.loc36_11.2: ref %Base = class_element_access %.loc36_11.1, element0 +// CHECK:STDOUT: %.loc36_11.3: ref %Base = converted %.loc36_11.1, %.loc36_11.2 +// CHECK:STDOUT: %.loc36_11.4: %Base = acquire_value %.loc36_11.3 +// CHECK:STDOUT: %Derived.SelfBase.call: init %i32 = call %Derived.SelfBase.bound(%.loc36_11.4) // CHECK:STDOUT: return %Derived.SelfBase.call // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/template/member_access.carbon b/toolchain/check/testdata/generic/template/member_access.carbon index 7fdac0bdc924..19f30229a9fe 100644 --- a/toolchain/check/testdata/generic/template/member_access.carbon +++ b/toolchain/check/testdata/generic/template/member_access.carbon @@ -344,12 +344,11 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: %inst.specific_inst: = inst_value [concrete] { // CHECK:STDOUT: %.24c: %D = specific_inst @F.%x.ref, @F(%D) // CHECK:STDOUT: } -// CHECK:STDOUT: %inst.splice_block.edc: = inst_value [concrete] { -// CHECK:STDOUT: %.859: ref %i32 = splice_block %.b2f { -// CHECK:STDOUT: %.179: %C = as_compatible %.24c -// CHECK:STDOUT: %.8a5: ref %C = class_element_access %.179, element0 -// CHECK:STDOUT: %.313: ref %C = converted %.24c, %.8a5 -// CHECK:STDOUT: %.b2f: ref %i32 = class_element_access %.313, element0 +// CHECK:STDOUT: %inst.splice_block.040: = inst_value [concrete] { +// CHECK:STDOUT: %.05c: ref %i32 = splice_block %.287 { +// CHECK:STDOUT: %.ff4: ref %C = class_element_access %.24c, element0 +// CHECK:STDOUT: %.07e: ref %C = converted %.24c, %.ff4 +// CHECK:STDOUT: %.287: ref %i32 = class_element_access %.07e, element0 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %inst.splice_block.edd: = inst_value [concrete] { @@ -447,7 +446,7 @@ fn G(d: D) -> i32 { // CHECK:STDOUT: %require_complete => constants.%complete_type.756 // CHECK:STDOUT: %.loc10_11.4 => constants.%inst.specific_inst // CHECK:STDOUT: %.loc10_11.5 => invalid -// CHECK:STDOUT: %.loc10_11.6 => constants.%inst.splice_block.edc +// CHECK:STDOUT: %.loc10_11.6 => constants.%inst.splice_block.040 // CHECK:STDOUT: %.loc10_11.7 => constants.%i32 // CHECK:STDOUT: %.loc10_11.8 => invalid // CHECK:STDOUT: %.loc10_17.8 => constants.%inst.splice_block.edd diff --git a/toolchain/check/testdata/impl/impl_thunk.carbon b/toolchain/check/testdata/impl/impl_thunk.carbon index 013f84d01c26..0d72e035e6ff 100644 --- a/toolchain/check/testdata/impl/impl_thunk.carbon +++ b/toolchain/check/testdata/impl/impl_thunk.carbon @@ -541,7 +541,7 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.48cdab.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1 [concrete = constants.%B.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.param, %F.ref // CHECK:STDOUT: -// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9) +// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8) // CHECK:STDOUT: %.loc14_37.1: %ptr.6b6 = value_of_initializer %B.as.X.impl.F.call // CHECK:STDOUT: %.loc14_37.2: %ptr.6b6 = converted %B.as.X.impl.F.call, %.loc14_37.1 // CHECK:STDOUT: %.loc14_37.3: ref %C = deref %.loc14_37.2 @@ -611,7 +611,7 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.48cdab.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc13_26.1 [concrete = constants.%B.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.param, %F.ref // CHECK:STDOUT: -// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.6, %.10) +// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.5, %.8) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -706,7 +706,7 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.48cdab.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1 [concrete = constants.%B.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.param, %F.ref // CHECK:STDOUT: -// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9) +// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8) // CHECK:STDOUT: %.loc14_37.1: %ptr.6b6 = value_of_initializer %B.as.X.impl.F.call // CHECK:STDOUT: %.loc14_37.2: %ptr.6b6 = converted %B.as.X.impl.F.call, %.loc14_37.1 // CHECK:STDOUT: %.loc14_37.3: ref %C = deref %.loc14_37.2 @@ -812,7 +812,7 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.48cdab.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1 [concrete = constants.%B.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.param, %F.ref // CHECK:STDOUT: -// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9) +// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8) // CHECK:STDOUT: %.loc14_37.1: %ptr.6b6 = value_of_initializer %B.as.X.impl.F.call // CHECK:STDOUT: %.loc14_37.2: %ptr.6b6 = converted %B.as.X.impl.F.call, %.loc14_37.1 // CHECK:STDOUT: %.loc14_37.3: ref %C = deref %.loc14_37.2 @@ -882,7 +882,7 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.48cdab.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc13_30.1 [concrete = constants.%B.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.param, %F.ref // CHECK:STDOUT: -// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.6, %.9) +// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.5, %.7) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -974,6 +974,7 @@ impl () as I({}) { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %struct_type.base.cb7: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %X.type: type = facet_type <@X> [concrete] // CHECK:STDOUT: %X.impl_witness: = impl_witness @A.as.X.impl.%X.impl_witness_table [concrete] // CHECK:STDOUT: %.d83: Core.Form = init_form %B [concrete] @@ -985,8 +986,8 @@ impl () as I({}) { // CHECK:STDOUT: %X.facet: %X.type = facet_value %A, (%X.impl_witness) [concrete] // CHECK:STDOUT: %A.as.X.impl.F.type.48cdab.2: type = fn_type @A.as.X.impl.F.loc23_14.2 [concrete] // CHECK:STDOUT: %A.as.X.impl.F.bd5be1.2: %A.as.X.impl.F.type.48cdab.2 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc23_14.2 [concrete] -// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.4: type = fn_type @Destroy.WithSelf.Op.loc23_14.4 [concrete] +// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.4: %Destroy.WithSelf.Op.type.ef016f.4 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.X.impl: %A.ref as %X.ref { @@ -1021,13 +1022,12 @@ impl () as I({}) { // CHECK:STDOUT: %F.ref: %A.as.X.impl.F.type.48cdab.1 = name_ref F, @A.as.X.impl.%A.as.X.impl.F.decl.loc23_14.1 [concrete = constants.%A.as.X.impl.F.bd5be1.1] // CHECK:STDOUT: %.loc23_14.1: ref %B = temporary_storage // CHECK:STDOUT: %A.as.X.impl.F.call: init %B to %.loc23_14.1 = call %F.ref() -// CHECK:STDOUT: %.loc23_14.2: init %A = as_compatible %A.as.X.impl.F.call -// CHECK:STDOUT: %.loc23_14.3: ref %A = temporary %.loc23_14.1, %.loc23_14.2 -// CHECK:STDOUT: %.loc23_14.4: ref %A = class_element_access %.loc23_14.3, element0 -// CHECK:STDOUT: %.loc23_14.5: ref %A = converted %A.as.X.impl.F.call, %.loc23_14.4 -// CHECK:STDOUT: %.loc23_14.6: %A = acquire_value %.loc23_14.5 -// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: = bound_method %.loc23_14.3, constants.%Destroy.WithSelf.Op.403171.2 -// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%.loc23_14.3) +// CHECK:STDOUT: %.loc23_14.2: ref %B = temporary %.loc23_14.1, %A.as.X.impl.F.call +// CHECK:STDOUT: %.loc23_14.3: ref %A = class_element_access %.loc23_14.2, element0 +// CHECK:STDOUT: %.loc23_14.4: ref %A = converted %A.as.X.impl.F.call, %.loc23_14.3 +// CHECK:STDOUT: %.loc23_14.5: %A = acquire_value %.loc23_14.4 +// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: = bound_method %.loc23_14.2, constants.%Destroy.WithSelf.Op.403171.4 +// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%.loc23_14.2) // CHECK:STDOUT: return to %return.param // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1038,6 +1038,16 @@ impl () as I({}) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc23_14.3(%self.param: ref %struct_type.base.cb7) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc23_14.4(%self.param: ref %B) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- generic_function.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interop/cpp/class/import/access.carbon b/toolchain/check/testdata/interop/cpp/class/import/access.carbon index 86b772c70db1..5f19c584d9ac 100644 --- a/toolchain/check/testdata/interop/cpp/class/import/access.carbon +++ b/toolchain/check/testdata/interop/cpp/class/import/access.carbon @@ -1692,13 +1692,12 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d // CHECK:STDOUT: %instance_data.ref: %NonFunctionMemberPublic.elem = name_ref instance_data, @NonFunctionMemberPublic.%field_decl [concrete = @NonFunctionMemberPublic.%field_decl] -// CHECK:STDOUT: %.loc12_36.1: %NonFunctionMemberPublic = as_compatible %d.ref -// CHECK:STDOUT: %.loc12_36.2: ref %NonFunctionMemberPublic = class_element_access %.loc12_36.1, element0 -// CHECK:STDOUT: %.loc12_36.3: ref %NonFunctionMemberPublic = converted %d.ref, %.loc12_36.2 -// CHECK:STDOUT: %.loc12_36.4: ref %i32 = class_element_access %.loc12_36.3, element0 -// CHECK:STDOUT: %.loc12_36.5: %i32 = acquire_value %.loc12_36.4 +// CHECK:STDOUT: %.loc12_36.1: ref %NonFunctionMemberPublic = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc12_36.2: ref %NonFunctionMemberPublic = converted %d.ref, %.loc12_36.1 +// CHECK:STDOUT: %.loc12_36.3: ref %i32 = class_element_access %.loc12_36.2, element0 +// CHECK:STDOUT: %.loc12_36.4: %i32 = acquire_value %.loc12_36.3 // CHECK:STDOUT: %i32.loc12: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %instance_data: %i32 = wrapper_binding instance_data, %.loc12_36.5 +// CHECK:STDOUT: %instance_data: %i32 = wrapper_binding instance_data, %.loc12_36.4 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %instance_data.patt: %pattern_type.6b6 = value_binding_pattern instance_data [concrete = constants.%instance_data.patt] // CHECK:STDOUT: } @@ -1760,13 +1759,12 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %Derived = name_ref self, %self // CHECK:STDOUT: %instance_data.ref: %NonFunctionMemberProtected.elem = name_ref instance_data, @NonFunctionMemberProtected.%field_decl [concrete = @NonFunctionMemberProtected.%field_decl] -// CHECK:STDOUT: %.loc10_41.1: %NonFunctionMemberProtected = as_compatible %self.ref -// CHECK:STDOUT: %.loc10_41.2: ref %NonFunctionMemberProtected = class_element_access %.loc10_41.1, element0 -// CHECK:STDOUT: %.loc10_41.3: ref %NonFunctionMemberProtected = converted %self.ref, %.loc10_41.2 -// CHECK:STDOUT: %.loc10_41.4: ref %i32 = class_element_access %.loc10_41.3, element0 -// CHECK:STDOUT: %.loc10_41.5: %i32 = acquire_value %.loc10_41.4 +// CHECK:STDOUT: %.loc10_41.1: ref %NonFunctionMemberProtected = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc10_41.2: ref %NonFunctionMemberProtected = converted %self.ref, %.loc10_41.1 +// CHECK:STDOUT: %.loc10_41.3: ref %i32 = class_element_access %.loc10_41.2, element0 +// CHECK:STDOUT: %.loc10_41.4: %i32 = acquire_value %.loc10_41.3 // CHECK:STDOUT: %i32.loc10: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %instance_data: %i32 = wrapper_binding instance_data, %.loc10_41.5 +// CHECK:STDOUT: %instance_data: %i32 = wrapper_binding instance_data, %.loc10_41.4 // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %instance_data.patt: %pattern_type.6b6 = value_binding_pattern instance_data [concrete = constants.%instance_data.patt] // CHECK:STDOUT: } @@ -2598,17 +2596,15 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: %instance.ref.loc24: ref %Public = name_ref instance, %instance // CHECK:STDOUT: %PublicInstance.ref: %Public.PublicInstance.cpp_overload_set.type = name_ref PublicInstance, imports.%Public.PublicInstance.cpp_overload_set.value [concrete = constants.%Public.PublicInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc24: = bound_method %instance.ref.loc24, %PublicInstance.ref -// CHECK:STDOUT: %.loc24_5.1: ref %Base = as_compatible %instance.ref.loc24 -// CHECK:STDOUT: %.loc24_5.2: ref %Base = class_element_access %.loc24_5.1, element0 -// CHECK:STDOUT: %.loc24_5.3: ref %Base = converted %instance.ref.loc24, %.loc24_5.2 -// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.3) +// CHECK:STDOUT: %.loc24_5.1: ref %Base = class_element_access %instance.ref.loc24, element0 +// CHECK:STDOUT: %.loc24_5.2: ref %Base = converted %instance.ref.loc24, %.loc24_5.1 +// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.2) // CHECK:STDOUT: %instance.ref.loc26: ref %Public = name_ref instance, %instance // CHECK:STDOUT: %ProtectedInstance.ref: %Public.ProtectedInstance.cpp_overload_set.type = name_ref ProtectedInstance, imports.%Public.ProtectedInstance.cpp_overload_set.value [concrete = constants.%Public.ProtectedInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc26: = bound_method %instance.ref.loc26, %ProtectedInstance.ref -// CHECK:STDOUT: %.loc26_5.1: ref %Base = as_compatible %instance.ref.loc26 -// CHECK:STDOUT: %.loc26_5.2: ref %Base = class_element_access %.loc26_5.1, element0 -// CHECK:STDOUT: %.loc26_5.3: ref %Base = converted %instance.ref.loc26, %.loc26_5.2 -// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.3) +// CHECK:STDOUT: %.loc26_5.1: ref %Base = class_element_access %instance.ref.loc26, element0 +// CHECK:STDOUT: %.loc26_5.2: ref %Base = converted %instance.ref.loc26, %.loc26_5.1 +// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.2) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2624,17 +2620,15 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: %instance.ref.loc36: ref %Public = name_ref instance, %instance // CHECK:STDOUT: %PublicInstance.ref.loc36: %Public.PublicInstance.cpp_overload_set.type = name_ref PublicInstance, imports.%Public.PublicInstance.cpp_overload_set.value [concrete = constants.%Public.PublicInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc36: = bound_method %instance.ref.loc36, %PublicInstance.ref.loc36 -// CHECK:STDOUT: %.loc36_3.1: ref %Base = as_compatible %instance.ref.loc36 -// CHECK:STDOUT: %.loc36_3.2: ref %Base = class_element_access %.loc36_3.1, element0 -// CHECK:STDOUT: %.loc36_3.3: ref %Base = converted %instance.ref.loc36, %.loc36_3.2 -// CHECK:STDOUT: %Base.PublicInstance.call.loc36: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc36_3.3) +// CHECK:STDOUT: %.loc36_3.1: ref %Base = class_element_access %instance.ref.loc36, element0 +// CHECK:STDOUT: %.loc36_3.2: ref %Base = converted %instance.ref.loc36, %.loc36_3.1 +// CHECK:STDOUT: %Base.PublicInstance.call.loc36: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc36_3.2) // CHECK:STDOUT: %instance.ref.loc37: ref %Public = name_ref instance, %instance // CHECK:STDOUT: %PublicInstance.ref.loc37: %Public.PublicInstance.cpp_overload_set.type = name_ref PublicInstance, imports.%Public.PublicInstance.cpp_overload_set.value [concrete = constants.%Public.PublicInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc37: = bound_method %instance.ref.loc37, %PublicInstance.ref.loc37 -// CHECK:STDOUT: %.loc37_3.1: ref %Base = as_compatible %instance.ref.loc37 -// CHECK:STDOUT: %.loc37_3.2: ref %Base = class_element_access %.loc37_3.1, element0 -// CHECK:STDOUT: %.loc37_3.3: ref %Base = converted %instance.ref.loc37, %.loc37_3.2 -// CHECK:STDOUT: %Base.PublicInstance.call.loc37: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc37_3.3) +// CHECK:STDOUT: %.loc37_3.1: ref %Base = class_element_access %instance.ref.loc37, element0 +// CHECK:STDOUT: %.loc37_3.2: ref %Base = converted %instance.ref.loc37, %.loc37_3.1 +// CHECK:STDOUT: %Base.PublicInstance.call.loc37: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc37_3.2) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2753,17 +2747,15 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: %instance.ref.loc24: ref %Protected = name_ref instance, %instance // CHECK:STDOUT: %PublicInstance.ref: %Protected.PublicInstance.cpp_overload_set.type = name_ref PublicInstance, imports.%Protected.PublicInstance.cpp_overload_set.value [concrete = constants.%Protected.PublicInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc24: = bound_method %instance.ref.loc24, %PublicInstance.ref -// CHECK:STDOUT: %.loc24_5.1: ref %Base = as_compatible %instance.ref.loc24 -// CHECK:STDOUT: %.loc24_5.2: ref %Base = class_element_access %.loc24_5.1, element0 -// CHECK:STDOUT: %.loc24_5.3: ref %Base = converted %instance.ref.loc24, %.loc24_5.2 -// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.3) +// CHECK:STDOUT: %.loc24_5.1: ref %Base = class_element_access %instance.ref.loc24, element0 +// CHECK:STDOUT: %.loc24_5.2: ref %Base = converted %instance.ref.loc24, %.loc24_5.1 +// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.2) // CHECK:STDOUT: %instance.ref.loc26: ref %Protected = name_ref instance, %instance // CHECK:STDOUT: %ProtectedInstance.ref: %Protected.ProtectedInstance.cpp_overload_set.type = name_ref ProtectedInstance, imports.%Protected.ProtectedInstance.cpp_overload_set.value [concrete = constants.%Protected.ProtectedInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc26: = bound_method %instance.ref.loc26, %ProtectedInstance.ref -// CHECK:STDOUT: %.loc26_5.1: ref %Base = as_compatible %instance.ref.loc26 -// CHECK:STDOUT: %.loc26_5.2: ref %Base = class_element_access %.loc26_5.1, element0 -// CHECK:STDOUT: %.loc26_5.3: ref %Base = converted %instance.ref.loc26, %.loc26_5.2 -// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.3) +// CHECK:STDOUT: %.loc26_5.1: ref %Base = class_element_access %instance.ref.loc26, element0 +// CHECK:STDOUT: %.loc26_5.2: ref %Base = converted %instance.ref.loc26, %.loc26_5.1 +// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.2) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2855,19 +2847,17 @@ fn Call(var instance: Cpp.PublicPrivate) { // CHECK:STDOUT: %instance.ref.loc24: ref %PublicProtected = name_ref instance, %instance // CHECK:STDOUT: %PublicInstance.ref: %PublicProtected.PublicInstance.cpp_overload_set.type = name_ref PublicInstance, imports.%PublicProtected.PublicInstance.cpp_overload_set.value [concrete = constants.%PublicProtected.PublicInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc24: = bound_method %instance.ref.loc24, %PublicInstance.ref -// CHECK:STDOUT: %.loc24_5.1: ref %Base = as_compatible %instance.ref.loc24 -// CHECK:STDOUT: %.loc24_5.2: ref %Protected = class_element_access %.loc24_5.1, element0 -// CHECK:STDOUT: %.loc24_5.3: ref %Base = class_element_access %.loc24_5.2, element0 -// CHECK:STDOUT: %.loc24_5.4: ref %Base = converted %instance.ref.loc24, %.loc24_5.3 -// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.4) +// CHECK:STDOUT: %.loc24_5.1: ref %Protected = class_element_access %instance.ref.loc24, element0 +// CHECK:STDOUT: %.loc24_5.2: ref %Base = class_element_access %.loc24_5.1, element0 +// CHECK:STDOUT: %.loc24_5.3: ref %Base = converted %instance.ref.loc24, %.loc24_5.2 +// CHECK:STDOUT: %Base.PublicInstance.call: init %empty_tuple.type = call imports.%Base.PublicInstance.decl(%.loc24_5.3) // CHECK:STDOUT: %instance.ref.loc26: ref %PublicProtected = name_ref instance, %instance // CHECK:STDOUT: %ProtectedInstance.ref: %PublicProtected.ProtectedInstance.cpp_overload_set.type = name_ref ProtectedInstance, imports.%PublicProtected.ProtectedInstance.cpp_overload_set.value [concrete = constants.%PublicProtected.ProtectedInstance.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc26: = bound_method %instance.ref.loc26, %ProtectedInstance.ref -// CHECK:STDOUT: %.loc26_5.1: ref %Base = as_compatible %instance.ref.loc26 -// CHECK:STDOUT: %.loc26_5.2: ref %Protected = class_element_access %.loc26_5.1, element0 -// CHECK:STDOUT: %.loc26_5.3: ref %Base = class_element_access %.loc26_5.2, element0 -// CHECK:STDOUT: %.loc26_5.4: ref %Base = converted %instance.ref.loc26, %.loc26_5.3 -// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.4) +// CHECK:STDOUT: %.loc26_5.1: ref %Protected = class_element_access %instance.ref.loc26, element0 +// CHECK:STDOUT: %.loc26_5.2: ref %Base = class_element_access %.loc26_5.1, element0 +// CHECK:STDOUT: %.loc26_5.3: ref %Base = converted %instance.ref.loc26, %.loc26_5.2 +// CHECK:STDOUT: %Base.ProtectedInstance.call: init %empty_tuple.type = call imports.%Base.ProtectedInstance.decl(%.loc26_5.3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/class/import/base.carbon b/toolchain/check/testdata/interop/cpp/class/import/base.carbon index 5b31153689d0..8557877b0e7a 100644 --- a/toolchain/check/testdata/interop/cpp/class/import/base.carbon +++ b/toolchain/check/testdata/interop/cpp/class/import/base.carbon @@ -568,11 +568,10 @@ class V { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %AcceptVal.ref: %AcceptVal.type = name_ref AcceptVal, file.%AcceptVal.decl [concrete = constants.%AcceptVal] // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d -// CHECK:STDOUT: %.loc16_13.1: %Base = as_compatible %d.ref -// CHECK:STDOUT: %.loc16_13.2: ref %Base = class_element_access %.loc16_13.1, element0 -// CHECK:STDOUT: %.loc16_13.3: ref %Base = converted %d.ref, %.loc16_13.2 -// CHECK:STDOUT: %.loc16_13.4: %Base = acquire_value %.loc16_13.3 -// CHECK:STDOUT: %AcceptVal.call: init %empty_tuple.type = call %AcceptVal.ref(%.loc16_13.4) +// CHECK:STDOUT: %.loc16_13.1: ref %Base = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc16_13.2: ref %Base = converted %d.ref, %.loc16_13.1 +// CHECK:STDOUT: %.loc16_13.3: %Base = acquire_value %.loc16_13.2 +// CHECK:STDOUT: %AcceptVal.call: init %empty_tuple.type = call %AcceptVal.ref(%.loc16_13.3) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -663,16 +662,15 @@ class V { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %FieldDerived = name_ref d, %d // CHECK:STDOUT: %a.ref: %FieldBase.elem = name_ref a, @FieldBase.%field_decl.1 [concrete = @FieldBase.%field_decl.1] -// CHECK:STDOUT: %.loc8_11.1: %FieldBase = as_compatible %d.ref -// CHECK:STDOUT: %.loc8_11.2: ref %FieldBase = class_element_access %.loc8_11.1, element0 -// CHECK:STDOUT: %.loc8_11.3: ref %FieldBase = converted %d.ref, %.loc8_11.2 -// CHECK:STDOUT: %.loc8_11.4: ref %i32 = class_element_access %.loc8_11.3, element0 -// CHECK:STDOUT: %.loc8_11.5: %i32 = acquire_value %.loc8_11.4 +// CHECK:STDOUT: %.loc8_11.1: ref %FieldBase = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc8_11.2: ref %FieldBase = converted %d.ref, %.loc8_11.1 +// CHECK:STDOUT: %.loc8_11.3: ref %i32 = class_element_access %.loc8_11.2, element0 +// CHECK:STDOUT: %.loc8_11.4: %i32 = acquire_value %.loc8_11.3 // CHECK:STDOUT: %impl.elem0: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] -// CHECK:STDOUT: %bound_method.loc8_11.1: = bound_method %.loc8_11.5, %impl.elem0 +// CHECK:STDOUT: %bound_method.loc8_11.1: = bound_method %.loc8_11.4, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc8_11.2: = bound_method %.loc8_11.5, %specific_fn -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc8_11.2(%.loc8_11.5) +// CHECK:STDOUT: %bound_method.loc8_11.2: = bound_method %.loc8_11.4, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc8_11.2(%.loc8_11.4) // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call // CHECK:STDOUT: } // CHECK:STDOUT: @@ -682,16 +680,15 @@ class V { // CHECK:STDOUT: %Cpp.ref.loc14: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %FieldBase.ref: type = name_ref FieldBase, imports.%FieldBase.decl [concrete = constants.%FieldBase] // CHECK:STDOUT: %b.ref: %FieldBase.elem = name_ref b, @FieldBase.%field_decl.2 [concrete = @FieldBase.%field_decl.2] -// CHECK:STDOUT: %.loc14_11.1: %FieldBase = as_compatible %d.ref -// CHECK:STDOUT: %.loc14_11.2: ref %FieldBase = class_element_access %.loc14_11.1, element0 -// CHECK:STDOUT: %.loc14_11.3: ref %FieldBase = converted %d.ref, %.loc14_11.2 -// CHECK:STDOUT: %.loc14_11.4: ref %i32 = class_element_access %.loc14_11.3, element1 -// CHECK:STDOUT: %.loc14_11.5: %i32 = acquire_value %.loc14_11.4 +// CHECK:STDOUT: %.loc14_11.1: ref %FieldBase = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc14_11.2: ref %FieldBase = converted %d.ref, %.loc14_11.1 +// CHECK:STDOUT: %.loc14_11.3: ref %i32 = class_element_access %.loc14_11.2, element1 +// CHECK:STDOUT: %.loc14_11.4: %i32 = acquire_value %.loc14_11.3 // CHECK:STDOUT: %impl.elem0: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6] -// CHECK:STDOUT: %bound_method.loc14_11.1: = bound_method %.loc14_11.5, %impl.elem0 +// CHECK:STDOUT: %bound_method.loc14_11.1: = bound_method %.loc14_11.4, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc14_11.2: = bound_method %.loc14_11.5, %specific_fn -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc14_11.2(%.loc14_11.5) +// CHECK:STDOUT: %bound_method.loc14_11.2: = bound_method %.loc14_11.4, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc14_11.2(%.loc14_11.4) // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call // CHECK:STDOUT: } // CHECK:STDOUT: @@ -738,11 +735,10 @@ class V { // CHECK:STDOUT: %d.ref: %MethodDerived = name_ref d, %d // CHECK:STDOUT: %f.ref: %MethodDerived.f.cpp_overload_set.type = name_ref f, imports.%MethodDerived.f.cpp_overload_set.value [concrete = constants.%MethodDerived.f.cpp_overload_set.value] // CHECK:STDOUT: %bound_method: = bound_method %d.ref, %f.ref -// CHECK:STDOUT: %.loc8_3.1: %MethodBase = as_compatible %d.ref -// CHECK:STDOUT: %.loc8_3.2: ref %MethodBase = class_element_access %.loc8_3.1, element0 -// CHECK:STDOUT: %.loc8_3.3: ref %MethodBase = converted %d.ref, %.loc8_3.2 -// CHECK:STDOUT: %.loc8_3.4: %MethodBase = acquire_value %.loc8_3.3 -// CHECK:STDOUT: %f__carbon_thunk.call: init %empty_tuple.type = call imports.%f__carbon_thunk.decl(%.loc8_3.4) +// CHECK:STDOUT: %.loc8_3.1: ref %MethodBase = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc8_3.2: ref %MethodBase = converted %d.ref, %.loc8_3.1 +// CHECK:STDOUT: %.loc8_3.3: %MethodBase = acquire_value %.loc8_3.2 +// CHECK:STDOUT: %f__carbon_thunk.call: init %empty_tuple.type = call imports.%f__carbon_thunk.decl(%.loc8_3.3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -753,11 +749,10 @@ class V { // CHECK:STDOUT: %MethodBase.ref: type = name_ref MethodBase, imports.%MethodBase.decl [concrete = constants.%MethodBase] // CHECK:STDOUT: %g.ref: %MethodBase.g.cpp_overload_set.type = name_ref g, imports.%MethodBase.g.cpp_overload_set.value [concrete = constants.%MethodBase.g.cpp_overload_set.value] // CHECK:STDOUT: %bound_method: = bound_method %d.ref, %g.ref -// CHECK:STDOUT: %.loc14_3.1: %MethodBase = as_compatible %d.ref -// CHECK:STDOUT: %.loc14_3.2: ref %MethodBase = class_element_access %.loc14_3.1, element0 -// CHECK:STDOUT: %.loc14_3.3: ref %MethodBase = converted %d.ref, %.loc14_3.2 -// CHECK:STDOUT: %.loc14_3.4: %MethodBase = acquire_value %.loc14_3.3 -// CHECK:STDOUT: %g__carbon_thunk.call: init %empty_tuple.type = call imports.%g__carbon_thunk.decl(%.loc14_3.4) +// CHECK:STDOUT: %.loc14_3.1: ref %MethodBase = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc14_3.2: ref %MethodBase = converted %d.ref, %.loc14_3.1 +// CHECK:STDOUT: %.loc14_3.3: %MethodBase = acquire_value %.loc14_3.2 +// CHECK:STDOUT: %g__carbon_thunk.call: init %empty_tuple.type = call imports.%g__carbon_thunk.decl(%.loc14_3.3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -768,11 +763,10 @@ class V { // CHECK:STDOUT: %MethodDerived.ref.loc23: type = name_ref MethodDerived, imports.%MethodDerived.decl [concrete = constants.%MethodDerived] // CHECK:STDOUT: %f.ref.loc23: %MethodDerived.f.cpp_overload_set.type = name_ref f, imports.%MethodDerived.f.cpp_overload_set.value [concrete = constants.%MethodDerived.f.cpp_overload_set.value] // CHECK:STDOUT: %bound_method.loc23: = bound_method %d.ref, %f.ref.loc23 -// CHECK:STDOUT: %.loc23_3.1: %MethodBase = as_compatible %d.ref -// CHECK:STDOUT: %.loc23_3.2: ref %MethodBase = class_element_access %.loc23_3.1, element0 -// CHECK:STDOUT: %.loc23_3.3: ref %MethodBase = converted %d.ref, %.loc23_3.2 -// CHECK:STDOUT: %.loc23_3.4: %MethodBase = acquire_value %.loc23_3.3 -// CHECK:STDOUT: %f__carbon_thunk.call.loc23: init %empty_tuple.type = call imports.%f__carbon_thunk.decl(%.loc23_3.4) +// CHECK:STDOUT: %.loc23_3.1: ref %MethodBase = class_element_access %d.ref, element0 +// CHECK:STDOUT: %.loc23_3.2: ref %MethodBase = converted %d.ref, %.loc23_3.1 +// CHECK:STDOUT: %.loc23_3.3: %MethodBase = acquire_value %.loc23_3.2 +// CHECK:STDOUT: %f__carbon_thunk.call.loc23: init %empty_tuple.type = call imports.%f__carbon_thunk.decl(%.loc23_3.3) // CHECK:STDOUT: %b.ref: %MethodBase = name_ref b, %b // CHECK:STDOUT: %Cpp.ref.loc24: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %MethodDerived.ref.loc24: type = name_ref MethodDerived, imports.%MethodDerived.decl [concrete = constants.%MethodDerived] diff --git a/toolchain/lower/testdata/class/convert.carbon b/toolchain/lower/testdata/class/convert.carbon index a25071ac6023..4fb2a529c1a4 100644 --- a/toolchain/lower/testdata/class/convert.carbon +++ b/toolchain/lower/testdata/class/convert.carbon @@ -10,6 +10,9 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/class/convert.carbon +// --- class_to_int.carbon +library "[[@TEST_NAME]]"; + class IntWrapper { var n: i32; } @@ -25,18 +28,28 @@ fn DoIt() { Consume(w); } +// --- partial_class_to_partial_base.carbon +library "[[@TEST_NAME]]"; + +base class B {} +base class D { extend base: B; } + +fn F(ref d: partial D) -> ref partial B { + return d; +} + // CHECK:STDOUT: ; --- -// CHECK:STDOUT: ; ModuleID = 'convert.carbon' -// CHECK:STDOUT: source_filename = "convert.carbon" +// CHECK:STDOUT: ; ModuleID = 'class_to_int.carbon' +// CHECK:STDOUT: source_filename = "class_to_int.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: @IntWrapper.val.loc24_3 = internal constant { i32 } { i32 42 } +// CHECK:STDOUT: @IntWrapper.val.loc14_3 = internal constant { i32 } { i32 42 } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define i32 @"_CConvert.IntWrapper.Main:ImplicitAs.84588f41d61dafba.Core"(ptr %self) #0 !dbg !30 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc18_40.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !35 -// CHECK:STDOUT: %.loc18_40.2 = load i32, ptr %.loc18_40.1.n, align 4, !dbg !35 -// CHECK:STDOUT: ret i32 %.loc18_40.2, !dbg !36 +// CHECK:STDOUT: %.loc8_40.1.n = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !35 +// CHECK:STDOUT: %.loc8_40.2 = load i32, ptr %.loc8_40.1.n, align 4, !dbg !35 +// CHECK:STDOUT: ret i32 %.loc8_40.2, !dbg !36 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind @@ -50,8 +63,8 @@ fn DoIt() { // CHECK:STDOUT: entry: // CHECK:STDOUT: %w.var = alloca { i32 }, align 4, !dbg !44 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %w.var), !dbg !44 -// CHECK:STDOUT: %.loc24_31.3.n = getelementptr inbounds nuw { i32 }, ptr %w.var, i32 0, i32 0, !dbg !45 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %w.var, ptr align 4 @IntWrapper.val.loc24_3, i64 4, i1 false), !dbg !44 +// CHECK:STDOUT: %.loc14_31.3.n = getelementptr inbounds nuw { i32 }, ptr %w.var, i32 0, i32 0, !dbg !45 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %w.var, ptr align 4 @IntWrapper.val.loc14_3, i64 4, i1 false), !dbg !44 // CHECK:STDOUT: %IntWrapper.as.ImplicitAs.impl.Convert.call = call i32 @"_CConvert.IntWrapper.Main:ImplicitAs.84588f41d61dafba.Core"(ptr %w.var), !dbg !47 // CHECK:STDOUT: call void @_CConsume.Main(i32 %IntWrapper.as.ImplicitAs.impl.Convert.call), !dbg !48 // CHECK:STDOUT: call void @"_COp.aecc0ff76a42614a:core.Destroy.Core"(ptr %w.var), !dbg !44 @@ -90,7 +103,7 @@ fn DoIt() { // CHECK:STDOUT: // CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} // CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} -// CHECK:STDOUT: !18 = !DIFile(filename: "convert.carbon", directory: "") +// CHECK:STDOUT: !18 = !DIFile(filename: "class_to_int.carbon", directory: "") // CHECK:STDOUT: !19 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !18, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) // CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) // CHECK:STDOUT: !21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) @@ -102,31 +115,59 @@ fn DoIt() { // CHECK:STDOUT: !27 = !DISubroutineType(types: !26) // CHECK:STDOUT: !28 = !{null, !21} // CHECK:STDOUT: !29 = !DISubroutineType(types: !28) -// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.IntWrapper.Main:ImplicitAs.84588f41d61dafba.Core", scope: null, file: !18, line: 18, type: !23, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !37) +// CHECK:STDOUT: !30 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.IntWrapper.Main:ImplicitAs.84588f41d61dafba.Core", scope: null, file: !18, line: 8, type: !23, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !37) // CHECK:STDOUT: !31 = !DILocalVariable(arg: 1, scope: !30, type: !21) -// CHECK:STDOUT: !35 = !DILocation(line: 18, column: 36, scope: !30) -// CHECK:STDOUT: !36 = !DILocation(line: 18, column: 29, scope: !30) +// CHECK:STDOUT: !35 = !DILocation(line: 8, column: 36, scope: !30) +// CHECK:STDOUT: !36 = !DILocation(line: 8, column: 29, scope: !30) // CHECK:STDOUT: !37 = !{!31} -// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "Consume", linkageName: "_CConsume.Main", scope: null, file: !18, line: 21, type: !25, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !42) +// CHECK:STDOUT: !38 = distinct !DISubprogram(name: "Consume", linkageName: "_CConsume.Main", scope: null, file: !18, line: 11, type: !25, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !42) // CHECK:STDOUT: !39 = !DILocalVariable(arg: 1, scope: !38, type: !20) -// CHECK:STDOUT: !41 = !DILocation(line: 21, column: 1, scope: !38) +// CHECK:STDOUT: !41 = !DILocation(line: 11, column: 1, scope: !38) // CHECK:STDOUT: !42 = !{!39} -// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "DoIt", linkageName: "_CDoIt.Main", scope: null, file: !18, line: 23, type: !27, spFlags: DISPFlagDefinition, unit: !19) -// CHECK:STDOUT: !44 = !DILocation(line: 24, column: 3, scope: !43) -// CHECK:STDOUT: !45 = !DILocation(line: 24, column: 23, scope: !43) -// CHECK:STDOUT: !47 = !DILocation(line: 25, column: 11, scope: !43) -// CHECK:STDOUT: !48 = !DILocation(line: 25, column: 3, scope: !43) -// CHECK:STDOUT: !49 = !DILocation(line: 23, column: 1, scope: !43) -// CHECK:STDOUT: !50 = distinct !DISubprogram(name: "Op", linkageName: "_COp.f58524831c37807e:core.Destroy.Core", scope: null, file: !18, line: 24, type: !25, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !53) +// CHECK:STDOUT: !43 = distinct !DISubprogram(name: "DoIt", linkageName: "_CDoIt.Main", scope: null, file: !18, line: 13, type: !27, spFlags: DISPFlagDefinition, unit: !19) +// CHECK:STDOUT: !44 = !DILocation(line: 14, column: 3, scope: !43) +// CHECK:STDOUT: !45 = !DILocation(line: 14, column: 23, scope: !43) +// CHECK:STDOUT: !47 = !DILocation(line: 15, column: 11, scope: !43) +// CHECK:STDOUT: !48 = !DILocation(line: 15, column: 3, scope: !43) +// CHECK:STDOUT: !49 = !DILocation(line: 13, column: 1, scope: !43) +// CHECK:STDOUT: !50 = distinct !DISubprogram(name: "Op", linkageName: "_COp.f58524831c37807e:core.Destroy.Core", scope: null, file: !18, line: 14, type: !25, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !53) // CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !50, type: !20) -// CHECK:STDOUT: !52 = !DILocation(line: 24, column: 3, scope: !50) +// CHECK:STDOUT: !52 = !DILocation(line: 14, column: 3, scope: !50) // CHECK:STDOUT: !53 = !{!51} -// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "Op", linkageName: "_COp.9edb2ca1f7e7a271:core.Destroy.Core", scope: null, file: !18, line: 24, type: !29, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !57) +// CHECK:STDOUT: !54 = distinct !DISubprogram(name: "Op", linkageName: "_COp.9edb2ca1f7e7a271:core.Destroy.Core", scope: null, file: !18, line: 14, type: !29, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !57) // CHECK:STDOUT: !55 = !DILocalVariable(arg: 1, scope: !54, type: !21) -// CHECK:STDOUT: !56 = !DILocation(line: 24, column: 3, scope: !54) +// CHECK:STDOUT: !56 = !DILocation(line: 14, column: 3, scope: !54) // CHECK:STDOUT: !57 = !{!55} -// CHECK:STDOUT: !58 = distinct !DISubprogram(name: "Op", linkageName: "_COp.aecc0ff76a42614a:core.Destroy.Core", scope: null, file: !18, line: 24, type: !29, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !61) +// CHECK:STDOUT: !58 = distinct !DISubprogram(name: "Op", linkageName: "_COp.aecc0ff76a42614a:core.Destroy.Core", scope: null, file: !18, line: 14, type: !29, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !61) // CHECK:STDOUT: !59 = !DILocalVariable(arg: 1, scope: !58, type: !21) -// CHECK:STDOUT: !60 = !DILocation(line: 24, column: 3, scope: !58) +// CHECK:STDOUT: !60 = !DILocation(line: 14, column: 3, scope: !58) // CHECK:STDOUT: !61 = !{!59} // CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'partial_class_to_partial_base.carbon' +// CHECK:STDOUT: source_filename = "partial_class_to_partial_base.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define ptr @_CF.Main(ptr %d) #0 !dbg !66 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc7_13.1.base = getelementptr inbounds nuw { {} }, ptr %d, i32 0, i32 0, !dbg !72 +// CHECK:STDOUT: ret ptr %.loc7_13.1.base, !dbg !72 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!63} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !62 = !DIFile(filename: "partial_class_to_partial_base.carbon", directory: "") +// CHECK:STDOUT: !63 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !62, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !64 = !{!21, !21} +// CHECK:STDOUT: !65 = !DISubroutineType(types: !64) +// CHECK:STDOUT: !66 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !62, line: 6, type: !65, spFlags: DISPFlagDefinition, unit: !63, retainedNodes: !73) +// CHECK:STDOUT: !67 = !DILocalVariable(arg: 1, scope: !66, type: !21) +// CHECK:STDOUT: !72 = !DILocation(line: 7, column: 5, scope: !66) +// CHECK:STDOUT: !73 = !{!67} +// CHECK:STDOUT: diff --git a/toolchain/lower/testdata/class/virtual.carbon b/toolchain/lower/testdata/class/virtual.carbon index 3b411773cb0e..d63345b55091 100644 --- a/toolchain/lower/testdata/class/virtual.carbon +++ b/toolchain/lower/testdata/class/virtual.carbon @@ -787,10 +787,10 @@ fn Use() { // CHECK:STDOUT: %.loc14_32.7.vptr = getelementptr inbounds nuw { ptr }, ptr %.loc14_32.6.base, i32 0, i32 0, !dbg !192 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %v.var, ptr align 8 @Derived.val.loc14_32.5, i64 8, i1 false), !dbg !192 // CHECK:STDOUT: store ptr @"_CDerived.Main.$vtable", ptr %.loc14_32.7.vptr, align 8, !dbg !192 -// CHECK:STDOUT: %.loc15_3.2.vptr = getelementptr inbounds nuw { ptr }, ptr %v.var, i32 0, i32 0, !dbg !195 -// CHECK:STDOUT: %Base.F.call.vtable = load ptr, ptr %.loc15_3.2.vptr, align 8, !dbg !195 +// CHECK:STDOUT: %.loc15_3.1.base = getelementptr inbounds nuw { { ptr } }, ptr %v.var, i32 0, i32 0, !dbg !195 +// CHECK:STDOUT: %Base.F.call.vtable = load ptr, ptr %.loc15_3.1.base, align 8, !dbg !195 // CHECK:STDOUT: %Base.F.call = call ptr @llvm.load.relative.i32(ptr %Base.F.call.vtable, i32 0), !dbg !195 -// CHECK:STDOUT: call void %Base.F.call(ptr %.loc15_3.2.vptr), !dbg !195 +// CHECK:STDOUT: call void %Base.F.call(ptr %.loc15_3.1.base), !dbg !195 // CHECK:STDOUT: call void @"_COp.b25525d21a9bd472:core.Destroy.Core"(ptr %v.var), !dbg !191 // CHECK:STDOUT: ret void, !dbg !196 // CHECK:STDOUT: } diff --git a/toolchain/lower/testdata/interop/cpp/class/import/base.carbon b/toolchain/lower/testdata/interop/cpp/class/import/base.carbon index edf50ff5d4e2..20e6fec40183 100644 --- a/toolchain/lower/testdata/interop/cpp/class/import/base.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/import/base.carbon @@ -76,8 +76,8 @@ fn Call(b: Cpp.B*) { // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define void @_CConvertVal.Main(ptr %b) #0 !dbg !34 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc13_13.2.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !37 -// CHECK:STDOUT: call void @_CAcceptVal.Main(ptr %.loc13_13.2.a), !dbg !38 +// CHECK:STDOUT: %.loc13_13.1.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !37 +// CHECK:STDOUT: call void @_CAcceptVal.Main(ptr %.loc13_13.1.base), !dbg !38 // CHECK:STDOUT: ret void, !dbg !39 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -124,10 +124,10 @@ fn Call(b: Cpp.B*) { // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define i32 @_CAccessVal.Main(ptr %b) #0 !dbg !53 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc7_11.2.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !58 -// CHECK:STDOUT: %.loc7_11.4.a = getelementptr inbounds nuw [4 x i8], ptr %.loc7_11.2.a, i32 0, i32 0, !dbg !58 -// CHECK:STDOUT: %.loc7_11.5 = load i32, ptr %.loc7_11.4.a, align 4, !dbg !58 -// CHECK:STDOUT: ret i32 %.loc7_11.5, !dbg !59 +// CHECK:STDOUT: %.loc7_11.1.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !58 +// CHECK:STDOUT: %.loc7_11.3.a = getelementptr inbounds nuw [4 x i8], ptr %.loc7_11.1.base, i32 0, i32 0, !dbg !58 +// CHECK:STDOUT: %.loc7_11.4 = load i32, ptr %.loc7_11.3.a, align 4, !dbg !58 +// CHECK:STDOUT: ret i32 %.loc7_11.4, !dbg !59 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } @@ -169,8 +169,8 @@ fn Call(b: Cpp.B*) { // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define void @_CCall.Main(ptr %b) #0 !dbg !63 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc7_4.3.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !66 -// CHECK:STDOUT: call void @_ZN1A1fEv(ptr %.loc7_4.3.a), !dbg !66 +// CHECK:STDOUT: %.loc7_4.2.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !66 +// CHECK:STDOUT: call void @_ZN1A1fEv(ptr %.loc7_4.2.base), !dbg !66 // CHECK:STDOUT: ret void, !dbg !67 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon b/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon index 595b37868f3c..91cdb1a326f5 100644 --- a/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/import/dynamic.carbon @@ -112,8 +112,8 @@ fn DoThing() { // CHECK:STDOUT: %.loc31_44.8.base = getelementptr inbounds nuw [16 x i8], ptr %.loc31_44.7.base, i32 0, i32 0, !dbg !62 // CHECK:STDOUT: %.loc31_44.9.vptr = getelementptr inbounds nuw [8 x i8], ptr %.loc31_44.8.base, i32 0, i32 0, !dbg !62 // CHECK:STDOUT: store ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr] }, ptr @_ZTVN6Carbon7DerivedE, i32 0, i32 0, i32 2), ptr %.loc31_44.9.vptr, align 8, !dbg !62 -// CHECK:STDOUT: %.loc32_11.3.base = getelementptr inbounds nuw [16 x i8], ptr %d.var, i32 0, i32 0, !dbg !66 -// CHECK:STDOUT: call void @_Z3UseR4Base(ptr %.loc32_11.3.base), !dbg !67 +// CHECK:STDOUT: %.loc32_11.2.base = getelementptr inbounds nuw { [16 x i8] }, ptr %d.var, i32 0, i32 0, !dbg !66 +// CHECK:STDOUT: call void @_Z3UseR4Base(ptr %.loc32_11.2.base), !dbg !67 // CHECK:STDOUT: call void @"_COp.b25525d21a9bd472:core.Destroy.Core"(ptr %d.var), !dbg !61 // CHECK:STDOUT: ret void, !dbg !68 // CHECK:STDOUT: } diff --git a/toolchain/lower/testdata/interop/cpp/class/import/method.carbon b/toolchain/lower/testdata/interop/cpp/class/import/method.carbon index d21cde3b9334..a1806f081029 100644 --- a/toolchain/lower/testdata/interop/cpp/class/import/method.carbon +++ b/toolchain/lower/testdata/interop/cpp/class/import/method.carbon @@ -269,11 +269,11 @@ fn F(ref r: Cpp.RefSelfA) { // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define void @_CUseVal.Main(ptr %a) #0 !dbg !62 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc7_4.3.vptr = getelementptr inbounds nuw [8 x i8], ptr %a, i32 0, i32 0, !dbg !65 -// CHECK:STDOUT: %Base.virt0.call.vtable = load ptr, ptr %.loc7_4.3.vptr, align 8, !dbg !65 +// CHECK:STDOUT: %.loc7_4.2.base = getelementptr inbounds nuw [16 x i8], ptr %a, i32 0, i32 0, !dbg !65 +// CHECK:STDOUT: %Base.virt0.call.vtable = load ptr, ptr %.loc7_4.2.base, align 8, !dbg !65 // CHECK:STDOUT: %Base.virt0.call = getelementptr ptr, ptr %Base.virt0.call.vtable, i32 0, !dbg !65 // CHECK:STDOUT: %Base.virt0.call.memptr.virtualfn = load ptr, ptr %Base.virt0.call, align 8, !dbg !65 -// CHECK:STDOUT: call void %Base.virt0.call.memptr.virtualfn(ptr %.loc7_4.3.vptr), !dbg !65 +// CHECK:STDOUT: call void %Base.virt0.call.memptr.virtualfn(ptr %.loc7_4.2.base), !dbg !65 // CHECK:STDOUT: %A.virt1.call.vtable = load ptr, ptr %a, align 8, !dbg !66 // CHECK:STDOUT: %A.virt1.call = getelementptr ptr, ptr %A.virt1.call.vtable, i32 1, !dbg !66 // CHECK:STDOUT: %A.virt1.call.memptr.virtualfn = load ptr, ptr %A.virt1.call, align 8, !dbg !66