// RUN: %empty-directory(%t) // -- Convert constants to decimal constants that LLVM will print // RUN: %{python} %utils/chex.py < %s > %t/keypaths.sil // RUN: %target-swift-frontend -module-name keypaths -emit-ir %s | %FileCheck %t/keypaths.sil --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-os sil_stage canonical import Swift public struct S: Hashable { public var x: Int public let y: String public var z: C public var reabstracted: () -> () public func hash(into hasher: inout Hasher) public static func ==(_: S, _: S) -> Bool } public class C: Hashable { public final var x: Int public final let y: String public final var z: S public var w: Int { get set } public init() public func hash(into hasher: inout Hasher) public static func ==(_: C, _: C) -> Bool } public class GC { public final var x: T } public struct G { public var x: T { get set } public subscript(x: U) -> T { get set } } public class C1: C { } public class C2: C1 { public var reabstracted: () -> () } public struct T { public var a: (Int, String) public let b: (f: String, g: Int) } public struct TG { public var a: (T, U, V) } typealias TGA = (a: T, b: U) sil_vtable C {} sil_vtable C1 {} sil_vtable C2 {} // CHECK: %TSi = type <{ [[WORD:i.*]] }> // -- %a: S.x // CHECK: [[KP_A:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic{{.*}}8keypaths1SV" // CHECK-SAME: @"symbolic Si // -- instantiable in-line, size 4 // CHECK-SAME: , // -- offset of S.x, mutable // CHECK-SAME: }> // -- %b: S.y // CHECK: [[KP_B:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic{{.*}}8keypaths1SV // CHECK-SAME: @"symbolic SS // -- instantiable in-line, size 4 // CHECK-SAME: , // -- offset of S.y, immutable // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %c: S.z // CHECK: [[KP_C:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic{{.*}}8keypaths1SV // CHECK-SAME: @"symbolic{{.*}}8keypaths1CC // -- instantiable in-line, size 4 // CHECK-SAME: , // -- offset of S.z, mutable // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %d: C.x // CHECK: [[KP_D:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 4 // CHECK-SAME: , // -- 0x0300_0000 (class) + mutable + offset of C.x // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %d1: C1.x // CHECK: [[KP_D1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 4 // CHECK-SAME: , // -- 0x0300_0000 (class) + mutable + offset of C.x // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %e: C.y // CHECK: [[KP_E:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 4 // CHECK-SAME: , // -- 0x0300_0000 (class) + immutable + offset of C.y // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %f: C.z // CHECK: [[KP_F:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 4 // CHECK-SAME: , // -- 0x0300_0000 (class) + mutable offset of C.z // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %g: S.z.x // CHECK: [[KP_G:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 12 // CHECK-SAME: , // -- offset of S.z // CHECK-32-SAME: , // CHECK-64-SAME: , // CHECK: @"symbolic // -- 0x0300_0000 (class) + offset of C.x // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %h: C.z.x // CHECK: [[KP_H:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // CHECK-SAME: , // -- 0x0300_0000 (class) + offset of C.z // CHECK-32-SAME: , // CHECK-64-SAME: , // CHECK: @"symbolic // -- offset of S.x // CHECK-SAME: }> // -- %k: computed // CHECK: [[KP_K:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 12 // CHECK-SAME: , // -- computed, get-only, identified by (indirected) function pointer, no args // CHECK-SAME: , // CHECK-SAME: @{{got.|"\\01__imp__?}}k_id // CHECK-SAME: ptr {{.*}}@k_get{{.*}} // -- %l: computed // CHECK: [[KP_L:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 16 // CHECK-SAME: , // -- computed, settable, nonmutating, identified by direct pointer, no args // CHECK-SAME: , // CHECK-SAME: @"$s8keypaths1CCMn" // CHECK-SAME: ptr @l_get // CHECK-SAME: ptr @l_set{{.*}} // -- %m: computed // CHECK: [[KP_M:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 16 // CHECK-SAME: , // -- computed, settable, nonmutating, identified by property offset, no args // CHECK-SAME: , // CHECK-SAME: [[WORD]] // CHECK-SAME: ptr {{.*}}@m_get // CHECK-SAME: ptr {{.*}}@m_set{{.*}} // -- %m2: reabstracted // Note: the contents here aren't interesting. The test triggered infinite // looping in the compiler at one point. // CHECK: [[KP_M:@keypath.*]] = private global <{ {{.*}} }> <{ // -- %t0: T.a.0 // CHECK: [[KP_T0:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 12 // CHECK-SAME: , // -- offset of T.a, mutable // CHECK-SAME: , // CHECK: @"symbolic // -- tuple element #0 of T.a // CHECK-SAME: }> // -- %t1: T.b.g // CHECK: [[KP_T1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: ptr @keypath_once // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- instantiable in-line, size 12 // CHECK-SAME: , // -- offset of T.b // CHECK-32-SAME: , // CHECK-64-SAME: , // CHECK: @"symbolic // -- tuple element #1 of T.b // CHECK-32-SAME: }> // CHECK-64-SAME: }> // -- %i: Gen.x // CHECK: [[KP_I:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: i32 0 // CHECK-SAME: @"generic environment l" // CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}" // CHECK-SAME: @"symbolic x" // -- size 8 // CHECK-SAME: i32 8, // -- struct with runtime-resolved offset, mutable // CHECK-SAME: , // CHECK-32-SAME: i32 16 }> // CHECK-64-SAME: i32 32 }> // -- %j: Gen.y // CHECK: [[KP_J:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: i32 0 // CHECK-SAME: @"generic environment l" // CHECK-SAME: @"symbolic{{[^"]*}}8keypaths3GenV{{[^"]*}}" // CHECK-SAME: @"symbolic x" // -- size 8 // CHECK-SAME: i32 8, // -- struct with runtime-resolved offset // CHECK-SAME: , // CHECK-32-SAME: i32 20 }> // CHECK-64-SAME: i32 36 }> // -- %tg0: TG.a.0 // CHECK: [[KP_TG0:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: @"generic environment r1_l" // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- struct with runtime-resolved offset, mutable // CHECK-SAME: , // -- offset of TG.a // CHECK-32-SAME: i32 20 // CHECK-64-SAME: i32 40 // CHECK-SAME: @"symbolic // -- tuple element with compile-time known offset, mutable // -- tuple element #0 of TG.a // CHECK-SAME: }> // -- %tg1: TG.a.2 // CHECK: [[KP_TG1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: @"generic environment r1_l" // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- struct with runtime-resolved offset, mutable // CHECK-SAME: , // -- offset of TG.a // CHECK-32-SAME: i32 20 // CHECK-64-SAME: i32 40 // CHECK-SAME: @"symbolic // -- tuple element with runtime-resolved offset, mutable // CHECK-SAME: , // -- tuple element #2 of TG.a // CHECK-32-SAME: i32 32 }> // CHECK-64-SAME: i32 64 }> // -- %tg2: TGA.1 // CHECK: [[KP_TG2:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: @"generic environment r0_l" // CHECK-SAME: @"symbolic // CHECK-SAME: @"symbolic // -- tuple element with runtime-resolved offset, mutable // CHECK-SAME: , // -- tuple element #1 of TGA // CHECK-32-SAME: i32 24 }> // CHECK-64-SAME: i32 48 }> // -- %gcx: GC.x // CHECK: [[KP_GCX:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ // CHECK-SAME: @"generic environment l" // CHECK-SAME: @"symbolic{{[^"]*}}8keypaths2GCC{{[^"]*}}" // CHECK-SAME: @"symbolic x" // -- class with runtime-resolved offset, mutable // CHECK-SAME: // CHECK-LABEL: @"generic environment SHRzSHR_r0_l" = linkonce_odr hidden constant // CHECK-SAME: i32 8193, i16 2, i8 -128, i8 -128, i32 128 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @stored_property_fixed_offsets() sil @stored_property_fixed_offsets : $@convention(thin) () -> () { entry: // CHECK: call ptr @swift_getKeyPath(ptr [[KP_A]], ptr undef) %a = keypath $KeyPath, (root $S; stored_property #S.x : $Int) strong_retain %a : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_B]], ptr undef) %b = keypath $KeyPath, (root $S; stored_property #S.y : $String) strong_retain %b : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_C]], ptr undef) %c = keypath $KeyPath, (root $S; stored_property #S.z : $C) strong_retain %c : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_D]], ptr undef) %d = keypath $KeyPath, (root $C; stored_property #C.x : $Int) strong_retain %d : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_D1]], ptr undef) %d1 = keypath $KeyPath, (root $C1; stored_property #C.x : $Int) strong_retain %d1 : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_E]], ptr undef) %e = keypath $KeyPath, (root $C; stored_property #C.y : $String) strong_retain %e : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_F]], ptr undef) %f = keypath $KeyPath, (root $C; stored_property #C.z : $S) strong_retain %f : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_G]], ptr undef) %g = keypath $KeyPath, (root $S; stored_property #S.z : $C; stored_property #C.x : $Int) strong_retain %g : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_H]], ptr undef) %h = keypath $KeyPath, (root $C; stored_property #C.z : $S; stored_property #S.x : $Int) strong_retain %h : $KeyPath %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) strong_retain %k : $KeyPath %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter, getter @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) strong_retain %l : $KeyPath %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) strong_retain %m : $KeyPath ()> %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) strong_retain %m2 : $KeyPath ()> // CHECK: call ptr @swift_getKeyPath(ptr [[KP_T0]], ptr undef) %t0 = keypath $KeyPath, (root $T; stored_property #T.a : $(Int, String); tuple_element #0 : $Int) strong_retain %t0 : $KeyPath // CHECK: call ptr @swift_getKeyPath(ptr [[KP_T1]], ptr undef) %t1 = keypath $KeyPath, (root $T; stored_property #T.b : $(f: String, g: Int); tuple_element #1 : $Int) strong_retain %t1 : $KeyPath return undef : $() } sil @k_id : $@convention(thin) () -> () sil @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int { bb0(%0 : $*Int, %1 : $*S): unreachable } sil @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int { bb0(%0 : $*Int, %1 : $*C): unreachable } sil @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () { bb0(%0 : $*Int, %1 : $*C): unreachable } sil @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } sil @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } sil @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> sil @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () struct Gen { var x: T var y: U } struct Foo { var foo: T } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @stored_property_generics(ptr %T, ptr %U) sil @stored_property_generics : $@convention(thin) () -> () { entry: // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: store ptr %T, ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_I]], ptr [[ARGS]]) %i = keypath $KeyPath, T>, (root $Gen; stored_property #Gen.x : $A) strong_retain %i : $KeyPath, T> // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: store ptr %U, ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_J]], ptr [[ARGS]]) %j = keypath $KeyPath, U>, (root $Gen; stored_property #Gen.y : $A) strong_retain %j : $KeyPath, U> // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8keypaths3FooVMa"([[WORD]] 0, ptr %T) // CHECK: [[FOO_T:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK: store ptr [[FOO_T]], ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_I]], ptr [[ARGS]]) %i2 = keypath $KeyPath,Foo>, Foo>, (root $Gen; stored_property #Gen.x : $A) > strong_retain %i2 : $KeyPath,Foo>, Foo> return undef : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @tuple_generics(ptr %T, ptr %U, ptr %V) sil @tuple_generics : $@convention(thin) () -> () { entry: // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: store ptr %T, ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_TG0]], ptr [[ARGS]]) %tg0 = keypath $KeyPath, T>, (root $TG; stored_property #TG.a : $(A,B,C); tuple_element #0 : $A) strong_retain %tg0 : $KeyPath, T> // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: store ptr %T, ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_TG1]], ptr [[ARGS]]) %tg1 = keypath $KeyPath, V>, (root $TG; stored_property #TG.a : $(A,B,C); tuple_element #2 : $C) strong_retain %tg1 : $KeyPath, V> // CHECK: [[ARGS:%.*]] = alloca i{{.*}} // CHECK: store ptr %T, ptr [[ARGS]] // CHECK: call ptr @swift_getKeyPath(ptr [[KP_TG2]], ptr [[ARGS]]) %tg2 = keypath $KeyPath, U>, (root $TGA; tuple_element #1 : $B) strong_retain %tg2 : $KeyPath, U> return undef : $() } sil @generic_class_stored_final : $@convention(thin) () -> () { entry: %gcx = keypath $ReferenceWritableKeyPath, T>, (root $GC; stored_property #GC.x: $T) strong_retain %gcx : $ReferenceWritableKeyPath, T> return undef : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics sil @computed_property_generics : $@convention(thin) () -> () { entry: %n = keypath $WritableKeyPath, (root $TTT; settable_property $UUU, id @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> ()) return undef : $() } sil @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU sil @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> () sil @computed_property_indices : $@convention(thin) (C, S, C, S, C, S) -> () { entry(%0 : $C, %1 : $S, %2 : $C, %3 : $S, %4 : $C, %5 : $S): %o = keypath $WritableKeyPath, ( root $S; settable_property $C, id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $C : $C], indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %p = keypath $WritableKeyPath, ( root $S; settable_property $C, id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %r = keypath $WritableKeyPath, ( root $S; settable_property $C, id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $S, id @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, getter @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, setter @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> (), indices [%$2 : $S : $S], indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) return undef : $() } sil @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C sil @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> () sil @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool sil @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int sil @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S sil @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> () sil @generic_computed_property_indices : $@convention(thin) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () { entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B): %s = keypath $WritableKeyPath, ( root $X; settable_property $Y, id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $X : $*X], indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %t = keypath $WritableKeyPath, ( root $X; settable_property $Y, id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %v = keypath $WritableKeyPath, ( root $X; settable_property $Y, id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $X, id @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, getter @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, setter @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed T, @in_guaranteed U, @in_guaranteed Int) -> (), indices [%$2 : $Y : $*Y], indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) strong_retain %s : $WritableKeyPath strong_retain %t : $WritableKeyPath strong_retain %v : $WritableKeyPath return undef : $() } sil @identity : $@convention(thin) () -> () { entry: %v = keypath $WritableKeyPath, (root $A; objc "self") %w = keypath $WritableKeyPath, (root $Int; objc "self") return undef : $() } public class GC2 { public final var x: T public var y: String } sil @class_constrained : $@convention(thin) () -> () { bb0: %k = keypath $KeyPath, <τ_0_0 where τ_0_0 : C> (root $τ_0_0; stored_property #C.y : $String) %t = tuple () return %t : $() } sil @generic_class_constrained : $@convention(thin) > () -> () { bb0: %k = keypath $KeyPath, <τ_0_0, τ_0_1 where τ_0_1 : GC2<τ_0_0>> (root $τ_0_1; stored_property #GC2.y : $String) %t = tuple () return %t : $() } sil @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed Int) -> @out B sil @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed B, @in_guaranteed A, @in_guaranteed Int) -> () sil @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool sil @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int sil @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed B, @in_guaranteed Int) -> @out A sil @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed Int) -> ()