Allow derived->base conversions with compatible qualifiers (#7415)

Move the existing derived->base conversion earlier in
`PerformBuiltinConversion`, into the block that handles qualifier
conversions. This allows, for example, converting from `partial Derived`
to `partial Base` -- see the tests in
`toolchain/check/testdata/class/inheritance/derived_to_base.carbon`.
This commit is contained in:
Nicholas Bishop
2026-06-24 21:08:24 +00:00
committed by GitHub
parent f2d99f31f0
commit 885b1110d5
20 changed files with 345 additions and 288 deletions
+13 -11
View File
@@ -1322,7 +1322,12 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
target.is_explicit_as()
? context.types().GetTransitiveUnqualifiedAdaptedType(value_type_id)
: context.types().GetUnqualifiedTypeAndQualifiers(value_type_id);
if (target_foundation_id == value_foundation_id) {
auto inheritance_path = ComputeInheritancePath(
context, loc_id, value_foundation_id, target_foundation_id);
if (inheritance_path && inheritance_path->empty()) {
inheritance_path = std::nullopt;
}
if (target_foundation_id == value_foundation_id || inheritance_path) {
auto category = SemIR::GetExprCategory(context.sem_ir(), value_id);
auto added_quals = target_quals & ~value_quals;
auto removed_quals = value_quals & ~target_quals;
@@ -1378,6 +1383,13 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
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
@@ -1448,16 +1460,6 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
target_quals.HasAnyOf(SemIR::TypeQualifiers::Partial));
}
}
// An expression of type T converts to U if T is a class derived from U.
//
// TODO: Combine this with the qualifiers and adapter conversion logic above
// to allow qualifiers and inheritance conversions to be performed together.
if (auto path = ComputeInheritancePath(context, loc_id, value_type_id,
target.type_id);
path && !path->empty()) {
return ConvertDerivedToBase(context, loc_id, value_id, *path);
}
}
// A pointer T* converts to [qualified] U* if T is the same as U, or is a
+19 -16
View File
@@ -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 `Derived` 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 `Abstract` that does not implement that interface [MissingImplInMemberAccess]
// CHECK:STDERR: let unused l: Abstract = {.base = {}} as Derived;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -859,11 +859,12 @@ 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.%.loc4 [concrete = @Abstract.%.loc4]
// 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: %.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: return %.loc18_13
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -946,10 +947,11 @@ 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: %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: %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: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -1008,15 +1010,16 @@ 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]
// CHECK:STDOUT: %.loc17_39.5: init %Abstract = as_compatible %.loc17_39.4 [concrete = constants.%Abstract.val.b13]
// 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: 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: %.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: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
// CHECK:STDOUT: %l: %Abstract = value_binding l, %.loc17_41.5
// CHECK:STDOUT: %l: %Abstract = value_binding l, %.loc17_41.6
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -397,29 +397,31 @@ 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.%.loc5 [concrete = @Shape.%.loc5]
// 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: %.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: %self.ref.loc13_21: %Circle = name_ref self, %self
// CHECK:STDOUT: %y.ref: %Shape.elem = name_ref y, @Shape.%.loc6 [concrete = @Shape.%.loc6]
// 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: %.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: %impl.elem0.loc13_17: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc13_17.1: <bound method> = bound_method %.loc13_17.4, %impl.elem0.loc13_17
// CHECK:STDOUT: %bound_method.loc13_17.1: <bound method> = bound_method %.loc13_17.5, %impl.elem0.loc13_17
// CHECK:STDOUT: %specific_fn.loc13_17: <specific function> = 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> = 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: %bound_method.loc13_17.2: <bound method> = 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: %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.4: %i32 = acquire_value %.loc13_25.3
// CHECK:STDOUT: %.loc13_25.5: %i32 = acquire_value %.loc13_25.4
// CHECK:STDOUT: %impl.elem0.loc13_25: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc13_25.1: <bound method> = bound_method %.loc13_25.4, %impl.elem0.loc13_25
// CHECK:STDOUT: %bound_method.loc13_25.1: <bound method> = bound_method %.loc13_25.5, %impl.elem0.loc13_25
// CHECK:STDOUT: %specific_fn.loc13_25: <specific function> = 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> = 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: %bound_method.loc13_25.2: <bound method> = 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: %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)
@@ -1623,9 +1625,10 @@ 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.%.loc5 [concrete = @A.%.loc5]
// 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: %.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: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
+13 -11
View File
@@ -249,15 +249,16 @@ 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.%.loc17 [concrete = @Base.%.loc17]
// 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: %.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: %impl.elem0: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc33_11.1: <bound method> = bound_method %.loc33_11.4, %impl.elem0
// CHECK:STDOUT: %bound_method.loc33_11.1: <bound method> = bound_method %.loc33_11.5, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = 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> = 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: %bound_method.loc33_11.2: <bound method> = 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: return %Int.as.Copy.impl.Op.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -283,10 +284,11 @@ 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.%.loc17 [concrete = @Base.%.loc17]
// CHECK:STDOUT: %.loc41_12.1: ref %Derived = deref %p.ref
// 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: %.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: %impl.elem0: %.ac9 = impl_witness_access constants.%Copy.impl_witness.ce1, element0 [concrete = constants.%ptr.as.Copy.impl.Op.d1c]
// CHECK:STDOUT: %bound_method.loc41_10.1: <bound method> = bound_method %addr, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%i32) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn]
@@ -251,11 +251,12 @@ 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.%.loc5 [concrete = @Base.%.loc5]
// 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: %.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: %y.ref: %Param.elem = name_ref y, @Param.%.loc9 [concrete = @Param.%.loc9]
// CHECK:STDOUT: %.loc17_13.1: ref %i32 = class_element_access %.loc17_11.3, element0
// CHECK:STDOUT: %.loc17_13.1: ref %i32 = class_element_access %.loc17_11.4, element0
// CHECK:STDOUT: %.loc17_13.2: %i32 = acquire_value %.loc17_13.1
// CHECK:STDOUT: %impl.elem0: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc17_13.1: <bound method> = bound_method %.loc17_13.2, %impl.elem0
@@ -437,11 +438,12 @@ 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.da1 [concrete = imports.%.866]
// 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: %.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: %y.ref: %Param.elem = name_ref y, imports.%Main.import_ref.573 [concrete = imports.%.8bf]
// CHECK:STDOUT: %.loc7_13.1: ref %i32 = class_element_access %.loc7_11.3, element0
// CHECK:STDOUT: %.loc7_13.1: ref %i32 = class_element_access %.loc7_11.4, element0
// CHECK:STDOUT: %.loc7_13.2: %i32 = acquire_value %.loc7_13.1
// CHECK:STDOUT: %impl.elem0: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc7_13.1: <bound method> = bound_method %.loc7_13.2, %impl.elem0
+12 -11
View File
@@ -146,27 +146,28 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 {
// CHECK:STDOUT: %require_complete.loc21_11: <witness> = require_complete_type %Base [symbolic = %require_complete.loc21_11 (constants.%require_complete.0fb)]
// CHECK:STDOUT: %require_complete.loc21_13: <witness> = require_complete_type %T.as_type.loc19_42.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.7: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %T.loc19_16.1 [symbolic = %.loc21_11.7 (constants.%.c29)]
// 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: %Copy.lookup_impl_witness: <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.7 (%.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.8 (%.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 function> = 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_42.1 (%Derived.e87)) -> out %return.param: @AccessBase.%T.as_type.loc19_42.1 (%T.as_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: @AccessBase.%Derived.loc19_42.1 (%Derived.e87) = name_ref x, %x
// CHECK:STDOUT: %b.ref: @AccessBase.%Base.elem (%Base.elem.209) = name_ref b, @Base.%.loc5 [concrete = @Base.%.loc5]
// 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_42.1 (%T.as_type) = class_element_access %.loc21_11.2, element0
// CHECK:STDOUT: %.loc21_11.4: @AccessBase.%T.as_type.loc19_42.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> = 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.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_42.1 (%T.as_type) = class_element_access %.loc21_11.3, element0
// CHECK:STDOUT: %.loc21_11.5: @AccessBase.%T.as_type.loc19_42.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> = bound_method %.loc21_11.5, %impl.elem0.loc21_11.1
// 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 function> = 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> = bound_method %.loc21_11.4, %specific_impl_fn.loc21_11.1
// CHECK:STDOUT: %bound_method.loc21_11.2: <bound method> = bound_method %.loc21_11.5, %specific_impl_fn.loc21_11.1
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %Copy.WithSelf.Op.call: init @AccessBase.%T.as_type.loc19_42.1 (%T.as_type) to %.loc19_48.1 = call %bound_method.loc21_11.2(%.loc21_11.4)
// CHECK:STDOUT: %Copy.WithSelf.Op.call: init @AccessBase.%T.as_type.loc19_42.1 (%T.as_type) to %.loc19_48.1 = call %bound_method.loc21_11.2(%.loc21_11.5)
// CHECK:STDOUT: return %Copy.WithSelf.Op.call to %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -149,10 +149,11 @@ 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.%.loc18 [concrete = @Base.%.loc18]
// 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: %.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: %impl.elem0: %.ac9 = impl_witness_access constants.%Copy.impl_witness.ce1, element0 [concrete = constants.%ptr.as.Copy.impl.Op.d1c]
// CHECK:STDOUT: %bound_method.loc29_10.1: <bound method> = bound_method %addr, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%i32) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn]
@@ -175,9 +175,10 @@ 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> = bound_method %.loc30_4.1, %F.ref
// 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: %.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: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -261,10 +261,11 @@ 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> = bound_method %a.ref, %F.ref
// 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: %.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: return %Base.F.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -275,10 +276,11 @@ 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> = bound_method %.loc34_11.1, %F.ref
// 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: %.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: return %Base.F.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -249,9 +249,10 @@ 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> = bound_method %.loc37_4.1, %F.ref.loc37
// 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: %.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: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -71,7 +71,7 @@ fn PassConstBPtr(p: const B*) {
//@dump-sem-ir-end
}
// --- fail_todo_qualified_non_ptr.carbon
// --- const_qualified_non_ptr.carbon
library "[[@TEST_NAME]]";
@@ -86,36 +86,41 @@ fn TakeConstA(p: const A);
fn PassNonConstB(p: B) {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE+10]]:14: error: cannot implicitly convert expression of type `B` to `const A` [ConversionFailure]
// CHECK:STDERR: TakeConstA(p);
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE+7]]:14: note: type `B` does not implement interface `Core.ImplicitAs(const A)` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: TakeConstA(p);
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE-10]]:15: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fn TakeConstA(p: const A);
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
TakeConstA(p);
//@dump-sem-ir-end
}
fn PassConstB(p: const B) {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE+10]]:14: error: cannot implicitly convert expression of type `const B` to `const A` [ConversionFailure]
// CHECK:STDERR: TakeConstA(p);
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE+7]]:14: note: type `const B` does not implement interface `Core.ImplicitAs(const A)` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: TakeConstA(p);
// CHECK:STDERR: ^
// CHECK:STDERR: fail_todo_qualified_non_ptr.carbon:[[@LINE-26]]:15: note: initializing function parameter [InCallToFunctionParam]
// CHECK:STDERR: fn TakeConstA(p: const A);
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
TakeConstA(p);
//@dump-sem-ir-end
}
// --- partial_qualified_non_ptr.carbon
library "[[@TEST_NAME]]";
base class A {
}
base class B {
extend base: A;
}
fn TakePartialA(p: partial A);
fn PassNonPartialB(b: B) {
//@dump-sem-ir-begin
TakePartialA(b);
//@dump-sem-ir-end
}
fn PassPartialB(b: partial B) {
//@dump-sem-ir-begin
TakePartialA(b);
//@dump-sem-ir-end
}
// CHECK:STDOUT: --- basic.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -126,9 +131,7 @@ fn PassConstB(p: const 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]
@@ -209,22 +212,23 @@ fn PassConstB(p: const B) {
// CHECK:STDOUT: %bound_method.953: <bound method> = 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: %A = struct_value (%int_1.0c6) [concrete]
// CHECK:STDOUT: %A.val.f6a: %A = struct_value (%int_1.0c6) [concrete]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3: <bound method> = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete]
// CHECK:STDOUT: %bound_method.3cb: <bound method> = 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, %int_2.295) [concrete]
// CHECK:STDOUT: %B.val: %B = struct_value (%A.val, %int_2.295) [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: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.485: <bound method> = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete]
// CHECK:STDOUT: %bound_method.763: <bound method> = 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: %.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.Op.type.1d8f74.8: type = fn_type @Destroy.Op.loc32_66.8 [concrete]
// CHECK:STDOUT: %Destroy.Op.1a2547.8: %Destroy.Op.type.1d8f74.8 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.084, %Destroy.Op.1a2547.8 [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.Op.type.1d8f74.4: type = fn_type @Destroy.Op.loc32_66.4 [concrete]
// CHECK:STDOUT: %Destroy.Op.1a2547.4: %Destroy.Op.type.1d8f74.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.320, %Destroy.Op.1a2547.4 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -370,12 +374,13 @@ fn PassConstB(p: const B) {
// CHECK:STDOUT: %a.patt: %pattern_type.9ef = value_binding_pattern a [concrete = constants.%a.patt.bb7b23.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c.ref: %C = name_ref c, %c
// 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: %.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: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A]
// CHECK:STDOUT: %a: %A = value_binding a, %.loc24_21.4
// CHECK:STDOUT: %a: %A = value_binding a, %.loc24_21.5
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -384,10 +389,11 @@ fn PassConstB(p: const 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 %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: %.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: %impl.elem0: %.e91 = impl_witness_access constants.%Copy.impl_witness.d19, element0 [concrete = constants.%ptr.as.Copy.impl.Op.5a8]
// CHECK:STDOUT: %bound_method.loc28_10.1: <bound method> = bound_method %addr, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%A) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn.d1a]
@@ -421,7 +427,7 @@ fn PassConstB(p: const 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]
// CHECK:STDOUT: %.loc32_55.4: init %A = as_compatible %.loc32_55.3 [concrete = constants.%A.val.f6a]
// CHECK:STDOUT: %impl.elem0.loc32_55: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc32_55.1: <bound method> = 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> = 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]
@@ -443,14 +449,15 @@ fn PassConstB(p: const 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: 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: %.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: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A]
// CHECK:STDOUT: %a: %A = value_binding a, %.loc32_66.6
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.084)
// CHECK:STDOUT: %a: %A = value_binding a, %.loc32_66.7
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.320)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -471,26 +478,6 @@ fn PassConstB(p: const B) {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.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.Op.loc32_66.6(%self.param: ref %B) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.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.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 {
@@ -531,7 +518,7 @@ fn PassConstB(p: const B) {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_qualified_non_ptr.carbon
// CHECK:STDOUT: --- const_qualified_non_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %A: type = class_type @A [concrete]
@@ -547,8 +534,11 @@ fn PassConstB(p: const 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: %.loc25: %const.b97 = converted %p.ref, <error> [concrete = <error>]
// CHECK:STDOUT: %TakeConstA.call: init %empty_tuple.type = call %TakeConstA.ref(<error>)
// 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.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)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -556,8 +546,47 @@ fn PassConstB(p: const 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: %.loc41: %const.b97 = converted %p.ref, <error> [concrete = <error>]
// CHECK:STDOUT: %TakeConstA.call: init %empty_tuple.type = call %TakeConstA.ref(<error>)
// 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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- partial_qualified_non_ptr.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %B: type = class_type @B [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %.3d6: type = partial_type %A [concrete]
// CHECK:STDOUT: %TakePartialA.type: type = fn_type @TakePartialA [concrete]
// CHECK:STDOUT: %TakePartialA: %TakePartialA.type = struct_value () [concrete]
// CHECK:STDOUT: %.640: type = partial_type %B [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @PassNonPartialB(%b.param: %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.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)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @PassPartialB(%b.param: %.640) {
// 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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -289,9 +289,10 @@ fn Run() {
// CHECK:STDOUT: %a: ref %Child = ref_binding a, %a.var
// CHECK:STDOUT: %a.ref.loc8: ref %Child = name_ref a, %a
// CHECK:STDOUT: %x.ref: %Base.elem = name_ref x, imports.%Main.import_ref.230 [concrete = imports.%.11f]
// 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: %.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: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc8: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc8_7.1: <bound method> = bound_method %int_2, %impl.elem0.loc8 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3]
@@ -299,14 +300,15 @@ fn Run() {
// CHECK:STDOUT: %bound_method.loc8_7.2: <bound method> = 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.3, %.loc8_7
// CHECK:STDOUT: assign %.loc8_4.4, %.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> = bound_method %a.ref.loc9, %F.ref
// 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: %.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: %Destroy.Op.bound: <bound method> = bound_method %a.var, constants.%Destroy.Op.1a2547.6
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%a.var)
// CHECK:STDOUT: return
@@ -253,17 +253,19 @@ 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> = bound_method %.loc35_4.1, %RefSelfBase.ref
// 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: %.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: %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> = bound_method %.loc36_11.1, %SelfBase.ref
// 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: %.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: return %Derived.SelfBase.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
+14 -24
View File
@@ -526,7 +526,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> = bound_method %self.param, %F.ref
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8)
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9)
// 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
@@ -596,7 +596,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> = bound_method %self.param, %F.ref
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.5, %.8)
// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.6, %.10)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -691,7 +691,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> = bound_method %self.param, %F.ref
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8)
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9)
// 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
@@ -797,7 +797,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> = bound_method %self.param, %F.ref
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.5, %.8)
// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.6b6 = call %B.as.X.impl.F.bound(%.6, %.9)
// 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
@@ -867,7 +867,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> = bound_method %self.param, %F.ref
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.5, %.7)
// CHECK:STDOUT: %B.as.X.impl.F.call: init %empty_tuple.type = call %B.as.X.impl.F.bound(%.6, %.9)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -878,7 +878,6 @@ 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: <witness> = impl_witness @A.as.X.impl.%X.impl_witness_table [concrete]
// CHECK:STDOUT: %.d83: Core.Form = init_form %B [concrete]
@@ -890,8 +889,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.Op.type.1d8f74.4: type = fn_type @Destroy.Op.loc23_14.4 [concrete]
// CHECK:STDOUT: %Destroy.Op.1a2547.4: %Destroy.Op.type.1d8f74.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc23_14.2 [concrete]
// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: impl @A.as.X.impl: %A.ref as %X.ref {
@@ -926,12 +925,13 @@ 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: 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.Op.bound: <bound method> = bound_method %.loc23_14.2, constants.%Destroy.Op.1a2547.4
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc23_14.2)
// 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.Op.bound: <bound method> = bound_method %.loc23_14.3, constants.%Destroy.Op.1a2547.2
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc23_14.3)
// CHECK:STDOUT: return <error> to %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -942,16 +942,6 @@ impl () as I({}) {
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.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.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 {
@@ -1696,12 +1696,13 @@ fn Call(var instance: Cpp.PublicPrivate) {
// CHECK:STDOUT: }
// CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d
// CHECK:STDOUT: %instance_data.ref: %S.elem = name_ref instance_data, @S.%.1 [concrete = @S.%.1]
// CHECK:STDOUT: %.loc12_36.1: ref %S = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc12_36.2: ref %S = 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: %.loc12_36.1: %S = as_compatible %d.ref
// CHECK:STDOUT: %.loc12_36.2: ref %S = class_element_access %.loc12_36.1, element0
// CHECK:STDOUT: %.loc12_36.3: ref %S = 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: %i32.loc12: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %instance_data: %i32 = value_binding instance_data, %.loc12_36.4
// CHECK:STDOUT: %instance_data: %i32 = value_binding instance_data, %.loc12_36.5
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %static_data.patt: %pattern_type.6b6 = value_binding_pattern static_data [concrete = constants.%static_data.patt.405]
// CHECK:STDOUT: }
@@ -1763,12 +1764,13 @@ fn Call(var instance: Cpp.PublicPrivate) {
// CHECK:STDOUT: }
// CHECK:STDOUT: %self.ref: %Derived = name_ref self, %self
// CHECK:STDOUT: %instance_data.ref: %C.elem = name_ref instance_data, @C.%.1 [concrete = @C.%.1]
// CHECK:STDOUT: %.loc10_41.1: ref %C = class_element_access %self.ref, element0
// CHECK:STDOUT: %.loc10_41.2: ref %C = 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: %.loc10_41.1: %C = as_compatible %self.ref
// CHECK:STDOUT: %.loc10_41.2: ref %C = class_element_access %.loc10_41.1, element0
// CHECK:STDOUT: %.loc10_41.3: ref %C = 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: %i32.loc10: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %instance_data: %i32 = value_binding instance_data, %.loc10_41.4
// CHECK:STDOUT: %instance_data: %i32 = value_binding instance_data, %.loc10_41.5
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %unqualified_static_data.patt: %pattern_type.6b6 = value_binding_pattern unqualified_static_data [concrete = constants.%unqualified_static_data.patt]
// CHECK:STDOUT: }
@@ -2597,15 +2599,17 @@ 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> = bound_method %instance.ref.loc24, %PublicInstance.ref
// 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: %.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: %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> = bound_method %instance.ref.loc26, %ProtectedInstance.ref
// 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: %.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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -2621,15 +2625,17 @@ 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> = bound_method %instance.ref.loc36, %PublicInstance.ref.loc36
// 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: %.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: %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> = bound_method %instance.ref.loc37, %PublicInstance.ref.loc37
// 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: %.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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -2748,15 +2754,17 @@ 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> = bound_method %instance.ref.loc24, %PublicInstance.ref
// 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: %.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: %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> = bound_method %instance.ref.loc26, %ProtectedInstance.ref
// 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: %.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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -2848,17 +2856,19 @@ 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> = bound_method %instance.ref.loc24, %PublicInstance.ref
// 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: %.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: %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> = bound_method %instance.ref.loc26, %ProtectedInstance.ref
// 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: %.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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
+36 -30
View File
@@ -568,10 +568,11 @@ 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: 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: %.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: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -662,15 +663,16 @@ class V {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d
// CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.1 [concrete = @Base.%.1]
// CHECK:STDOUT: %.loc8_11.1: ref %Base = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc8_11.2: ref %Base = 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: %.loc8_11.1: %Base = as_compatible %d.ref
// CHECK:STDOUT: %.loc8_11.2: ref %Base = class_element_access %.loc8_11.1, element0
// CHECK:STDOUT: %.loc8_11.3: ref %Base = 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: %impl.elem0: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc8_11.1: <bound method> = bound_method %.loc8_11.4, %impl.elem0
// CHECK:STDOUT: %bound_method.loc8_11.1: <bound method> = bound_method %.loc8_11.5, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = 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> = 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: %bound_method.loc8_11.2: <bound method> = 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: return %Int.as.Copy.impl.Op.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -680,15 +682,16 @@ class V {
// CHECK:STDOUT: %Cpp.ref.loc14: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Base.decl [concrete = constants.%Base]
// CHECK:STDOUT: %b.ref: %Base.elem = name_ref b, @Base.%.2 [concrete = @Base.%.2]
// CHECK:STDOUT: %.loc14_11.1: ref %Base = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc14_11.2: ref %Base = 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: %.loc14_11.1: %Base = as_compatible %d.ref
// CHECK:STDOUT: %.loc14_11.2: ref %Base = class_element_access %.loc14_11.1, element0
// CHECK:STDOUT: %.loc14_11.3: ref %Base = 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: %impl.elem0: %.7a6 = impl_witness_access constants.%Copy.impl_witness.0e0, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
// CHECK:STDOUT: %bound_method.loc14_11.1: <bound method> = bound_method %.loc14_11.4, %impl.elem0
// CHECK:STDOUT: %bound_method.loc14_11.1: <bound method> = bound_method %.loc14_11.5, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = 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> = 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: %bound_method.loc14_11.2: <bound method> = 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: return %Int.as.Copy.impl.Op.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -735,10 +738,11 @@ class V {
// CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d
// CHECK:STDOUT: %f.ref: %Derived.f.cpp_overload_set.type = name_ref f, imports.%Derived.f.cpp_overload_set.value [concrete = constants.%Derived.f.cpp_overload_set.value]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %d.ref, %f.ref
// CHECK:STDOUT: %.loc8_3.1: ref %Base = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc8_3.2: ref %Base = converted %d.ref, %.loc8_3.1
// CHECK:STDOUT: %.loc8_3.3: %Base = 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: %.loc8_3.1: %Base = as_compatible %d.ref
// CHECK:STDOUT: %.loc8_3.2: ref %Base = class_element_access %.loc8_3.1, element0
// CHECK:STDOUT: %.loc8_3.3: ref %Base = converted %d.ref, %.loc8_3.2
// CHECK:STDOUT: %.loc8_3.4: %Base = 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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -749,10 +753,11 @@ class V {
// CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Base.decl [concrete = constants.%Base]
// CHECK:STDOUT: %g.ref: %Base.g.cpp_overload_set.type = name_ref g, imports.%Base.g.cpp_overload_set.value [concrete = constants.%Base.g.cpp_overload_set.value]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %d.ref, %g.ref
// CHECK:STDOUT: %.loc14_3.1: ref %Base = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc14_3.2: ref %Base = converted %d.ref, %.loc14_3.1
// CHECK:STDOUT: %.loc14_3.3: %Base = 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: %.loc14_3.1: %Base = as_compatible %d.ref
// CHECK:STDOUT: %.loc14_3.2: ref %Base = class_element_access %.loc14_3.1, element0
// CHECK:STDOUT: %.loc14_3.3: ref %Base = converted %d.ref, %.loc14_3.2
// CHECK:STDOUT: %.loc14_3.4: %Base = 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: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -763,10 +768,11 @@ class V {
// CHECK:STDOUT: %Derived.ref.loc23: type = name_ref Derived, imports.%Derived.decl [concrete = constants.%Derived]
// CHECK:STDOUT: %f.ref.loc23: %Derived.f.cpp_overload_set.type = name_ref f, imports.%Derived.f.cpp_overload_set.value [concrete = constants.%Derived.f.cpp_overload_set.value]
// CHECK:STDOUT: %bound_method.loc23: <bound method> = bound_method %d.ref, %f.ref.loc23
// CHECK:STDOUT: %.loc23_3.1: ref %Base = class_element_access %d.ref, element0
// CHECK:STDOUT: %.loc23_3.2: ref %Base = converted %d.ref, %.loc23_3.1
// CHECK:STDOUT: %.loc23_3.3: %Base = 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: %.loc23_3.1: %Base = as_compatible %d.ref
// CHECK:STDOUT: %.loc23_3.2: ref %Base = class_element_access %.loc23_3.1, element0
// CHECK:STDOUT: %.loc23_3.3: ref %Base = converted %d.ref, %.loc23_3.2
// CHECK:STDOUT: %.loc23_3.4: %Base = 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: %b.ref: %Base = name_ref b, %b
// CHECK:STDOUT: %Cpp.ref.loc24: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %Derived.ref.loc24: type = name_ref Derived, imports.%Derived.decl [concrete = constants.%Derived]
+3 -3
View File
@@ -774,10 +774,10 @@ fn Use() {
// CHECK:STDOUT: %.loc14_32.7.vptr = getelementptr inbounds nuw { ptr }, ptr %.loc14_32.6.base, i32 0, i32 0, !dbg !15
// 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 !15
// CHECK:STDOUT: store ptr @"_CDerived.Main.$vtable", ptr %.loc14_32.7.vptr, align 8, !dbg !15
// CHECK:STDOUT: %.loc15_3.1.base = getelementptr inbounds nuw { { ptr } }, ptr %v.var, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: %Base.F.call.vtable = load ptr, ptr %.loc15_3.1.base, align 8, !dbg !17
// CHECK:STDOUT: %.loc15_3.2.vptr = getelementptr inbounds nuw { ptr }, ptr %v.var, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: %Base.F.call.vtable = load ptr, ptr %.loc15_3.2.vptr, align 8, !dbg !17
// CHECK:STDOUT: %Base.F.call = call ptr @llvm.load.relative.i32(ptr %Base.F.call.vtable, i32 0), !dbg !17
// CHECK:STDOUT: call void %Base.F.call(ptr %.loc15_3.1.base), !dbg !17
// CHECK:STDOUT: call void %Base.F.call(ptr %.loc15_3.2.vptr), !dbg !17
// CHECK:STDOUT: call void @"_COp.8185e3504351afa8:core.Destroy.Core"(ptr %v.var), !dbg !14
// CHECK:STDOUT: ret void, !dbg !18
// CHECK:STDOUT: }
@@ -75,8 +75,8 @@ fn Call(b: Cpp.B*) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CConvertVal.Main(ptr %b) #0 !dbg !18 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc13_13.1.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !23
// CHECK:STDOUT: call void @_CAcceptVal.Main(ptr %.loc13_13.1.base), !dbg !24
// CHECK:STDOUT: %.loc13_13.2.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !23
// CHECK:STDOUT: call void @_CAcceptVal.Main(ptr %.loc13_13.2.a), !dbg !24
// CHECK:STDOUT: ret void, !dbg !25
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -120,10 +120,10 @@ fn Call(b: Cpp.B*) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CAccessVal.Main(ptr %b) #0 !dbg !11 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc7_11.1.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !18
// CHECK:STDOUT: %.loc7_11.3.a = getelementptr inbounds nuw [4 x i8], ptr %.loc7_11.1.base, i32 0, i32 0, !dbg !18
// CHECK:STDOUT: %.loc7_11.4 = load i32, ptr %.loc7_11.3.a, align 4, !dbg !18
// CHECK:STDOUT: ret i32 %.loc7_11.4, !dbg !19
// CHECK:STDOUT: %.loc7_11.2.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !18
// CHECK:STDOUT: %.loc7_11.4.a = getelementptr inbounds nuw [4 x i8], ptr %.loc7_11.2.a, i32 0, i32 0, !dbg !18
// CHECK:STDOUT: %.loc7_11.5 = load i32, ptr %.loc7_11.4.a, align 4, !dbg !18
// CHECK:STDOUT: ret i32 %.loc7_11.5, !dbg !19
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
@@ -162,8 +162,8 @@ fn Call(b: Cpp.B*) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CCall.Main(ptr %b) #0 !dbg !11 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc7_4.2.base = getelementptr inbounds nuw [8 x i8], ptr %b, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: call void @_ZN1A1fEv(ptr %.loc7_4.2.base), !dbg !17
// CHECK:STDOUT: %.loc7_4.3.a = getelementptr inbounds nuw [4 x i8], ptr %b, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: call void @_ZN1A1fEv(ptr %.loc7_4.3.a), !dbg !17
// CHECK:STDOUT: ret void, !dbg !18
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -111,8 +111,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 !33
// CHECK:STDOUT: %.loc31_44.9.vptr = getelementptr inbounds nuw [8 x i8], ptr %.loc31_44.8.base, i32 0, i32 0, !dbg !33
// 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 !33
// CHECK:STDOUT: %.loc32_11.2.base = getelementptr inbounds nuw { [16 x i8] }, ptr %d.var, i32 0, i32 0, !dbg !35
// CHECK:STDOUT: call void @_Z3UseR4Base(ptr %.loc32_11.2.base), !dbg !36
// CHECK:STDOUT: %.loc32_11.3.base = getelementptr inbounds nuw [16 x i8], ptr %d.var, i32 0, i32 0, !dbg !35
// CHECK:STDOUT: call void @_Z3UseR4Base(ptr %.loc32_11.3.base), !dbg !36
// CHECK:STDOUT: call void @"_COp.8185e3504351afa8:core.Destroy.Core"(ptr %d.var), !dbg !32
// CHECK:STDOUT: ret void, !dbg !37
// CHECK:STDOUT: }
@@ -262,11 +262,11 @@ fn F(ref r: Cpp.A) {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CUseVal.Main(ptr %a) #0 !dbg !11 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc7_4.2.base = getelementptr inbounds nuw [16 x i8], ptr %a, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: %Base.virt0.call.vtable = load ptr, ptr %.loc7_4.2.base, align 8, !dbg !17
// CHECK:STDOUT: %.loc7_4.3.vptr = getelementptr inbounds nuw [8 x i8], ptr %a, i32 0, i32 0, !dbg !17
// CHECK:STDOUT: %Base.virt0.call.vtable = load ptr, ptr %.loc7_4.3.vptr, align 8, !dbg !17
// CHECK:STDOUT: %Base.virt0.call = getelementptr ptr, ptr %Base.virt0.call.vtable, i32 0, !dbg !17
// CHECK:STDOUT: %Base.virt0.call.memptr.virtualfn = load ptr, ptr %Base.virt0.call, align 8, !dbg !17
// CHECK:STDOUT: call void %Base.virt0.call.memptr.virtualfn(ptr %.loc7_4.2.base), !dbg !17
// CHECK:STDOUT: call void %Base.virt0.call.memptr.virtualfn(ptr %.loc7_4.3.vptr), !dbg !17
// CHECK:STDOUT: %A.virt1.call.vtable = load ptr, ptr %a, align 8, !dbg !18
// CHECK:STDOUT: %A.virt1.call = getelementptr ptr, ptr %A.virt1.call.vtable, i32 1, !dbg !18
// CHECK:STDOUT: %A.virt1.call.memptr.virtualfn = load ptr, ptr %A.virt1.call, align 8, !dbg !18