blob: 8e5d64ebdf8df0e0088b7709dd18b1c11793c69a [file] [log] [blame]
// RUN: rm -rf %t && mkdir -p %t
// -- Convert <i32 0x...> constants to decimal constants that LLVM will print
// RUN: %utils/chex.py < %s > %t/keypaths.sil
// RUN: %target-swift-frontend -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
struct S: Hashable {
var x: Int
let y: String
var z: C
var reabstracted: () -> ()
var hashValue: Int { get }
static func ==(_: S, _: S) -> Bool
}
class C: Hashable {
final var x: Int
final let y: String
final var z: S
var w: Int { get set }
init()
var hashValue: Int { get }
static func ==(_: C, _: C) -> Bool
}
sil_vtable C {}
// CHECK: %TSi = type <{ [[WORD:i.*]] }>
// -- %a: S.x
// CHECK: [[KP_A:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- offset of S.x
// CHECK-SAME: i32 0 }>
// -- %b: S.y
// CHECK: [[KP_B:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- offset of S.y
// CHECK-32-SAME: i32 4 }>
// CHECK-64-SAME: i32 8 }>
// -- %c: S.z
// CHECK: [[KP_C:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- offset of S.z
// CHECK-32-SAME: i32 16 }>
// CHECK-64-SAME: i32 32 }>
// -- %d: C.x
// CHECK: [[KP_D:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- 0x4000_0000 (class) + offset of C.x
// CHECK-32-SAME: <i32 0x4000_000c> }>
// CHECK-64-SAME: <i32 0x4000_0010> }>
// -- %e: C.y
// CHECK: [[KP_E:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- 0x4000_0000 (class) + offset of C.y
// CHECK-32-SAME: <i32 0x4000_0010> }>
// CHECK-64-SAME: <i32 0x4000_0018> }>
// -- %f: C.z
// CHECK: [[KP_F:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 4
// CHECK-SAME: <i32 0x8000_0004>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- 0x4000_0000 (class) + offset of C.z
// CHECK-32-SAME: <i32 0x4000_001c> }>
// CHECK-64-SAME: <i32 0x4000_0030> }>
// -- %g: S.z.x
// CHECK: [[KP_G:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 12
// CHECK-32-SAME: <i32 0x8000_000c>,
// -- instantiable in-line, size 20
// CHECK-64-SAME: <i32 0x8000_0014>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- offset of S.z
// CHECK-32-SAME: i32 16,
// CHECK-64-SAME: i32 32,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// CHECK: %swift.type* (i8*)*
// -- 0x4000_0000 (class) + offset of C.x
// CHECK-32-SAME: <i32 0x4000_000c> }>
// CHECK-64-SAME: <i32 0x4000_0010> }>
// -- %h: C.z.x
// CHECK: [[KP_H:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 12
// CHECK-32-SAME: <i32 0x8000_000c>,
// -- instantiable in-line, size 20
// CHECK-64-SAME: <i32 0x8000_0014>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- 0x4000_0000 (class) + offset of C.z
// CHECK-32-SAME: <i32 0x4000_001c>,
// CHECK-64-SAME: <i32 0x4000_0030>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// CHECK: %swift.type* (i8*)*
// -- offset of S.x
// CHECK-SAME: i32 0 }>
// -- %k: computed
// CHECK: [[KP_K:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 24
// CHECK-64-SAME: <i32 0x8000_0018>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- instantiable in-line, size 12
// CHECK-32-SAME: <i32 0x8000_000c>,
// -- computed, get-only, identified by function pointer, no args
// CHECK-SAME: <i32 0x2000_0000>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// CHECK-SAME: void ()* @k_id,
// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get }>
// -- %l: computed
// CHECK: [[KP_L:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 32
// CHECK-64-SAME: <i32 0x8000_0020>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- instantiable in-line, size 16
// CHECK-32-SAME: <i32 0x8000_0010>,
// -- computed, settable, nonmutating, identified by vtable, no args
// CHECK-SAME: <i32 0x2a00_0000>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// CHECK-SAME: [[WORD]]
// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get,
// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set }>
// -- %m: computed
// CHECK: [[KP_M:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)*
// CHECK-SAME: %swift.type* (i8*)*
// -- instantiable in-line, size 32
// CHECK-64-SAME: <i32 0x8000_0020>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- instantiable in-line, size 16
// CHECK-32-SAME: <i32 0x8000_0010>,
// -- computed, settable, nonmutating, identified by property offset, no args
// CHECK-SAME: <i32 0x3c00_0000>,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// CHECK-SAME: [[WORD]]
// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get,
// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set }>
// -- %i: Gen<A>.x
// CHECK: [[KP_I:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)* [[I_GET_GEN_A_A:@[a-z_.0-9]+]],
// CHECK-SAME: %swift.type* (i8*)* [[I_GET_A:@[a-z_.0-9]+]],
// -- size 8
// CHECK-SAME: i32 8,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- struct with runtime-resolved offset
// CHECK-SAME: <i32 0x1ffffffe>,
// CHECK-32-SAME: i32 8 }>
// CHECK-64-SAME: i32 16 }>
// -- %j: Gen<A>.y
// CHECK: [[KP_J:@keypath.*]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]] 0,
// CHECK-SAME: %swift.type* (i8*)* [[J_GET_GEN_A_A:@[a-z_.0-9]+]],
// CHECK-SAME: %swift.type* (i8*)* [[J_GET_A:@[a-z_.0-9]+]],
// -- size 8
// CHECK-SAME: i32 8,
// CHECK-64-SAME: [4 x i8] zeroinitializer,
// -- struct with runtime-resolved offset
// CHECK-SAME: <i32 0x1ffffffe>,
// CHECK-32-SAME: i32 12 }>
// CHECK-64-SAME: i32 24 }>
// CHECK-LABEL: define{{( protected)?}} swiftcc void @stored_property_fixed_offsets()
sil @stored_property_fixed_offsets : $@convention(thin) () -> () {
entry:
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_A]] to i8*), i8* undef)
%a = keypath $KeyPath<S, Int>, (root $S; stored_property #S.x : $Int)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_B]] to i8*), i8* undef)
%b = keypath $KeyPath<S, String>, (root $S; stored_property #S.y : $String)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_C]] to i8*), i8* undef)
%c = keypath $KeyPath<S, C>, (root $S; stored_property #S.z : $C)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_D]] to i8*), i8* undef)
%d = keypath $KeyPath<C, Int>, (root $C; stored_property #C.x : $Int)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_E]] to i8*), i8* undef)
%e = keypath $KeyPath<C, String>, (root $C; stored_property #C.y : $String)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_F]] to i8*), i8* undef)
%f = keypath $KeyPath<C, S>, (root $C; stored_property #C.z : $S)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_G]] to i8*), i8* undef)
%g = keypath $KeyPath<S, Int>, (root $S; stored_property #S.z : $C; stored_property #C.x : $Int)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_H]] to i8*), i8* undef)
%h = keypath $KeyPath<C, Int>, (root $C; stored_property #C.z : $S; stored_property #S.x : $Int)
%k = keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in S) -> @out Int)
%l = keypath $KeyPath<C, Int>, (root $C; settable_property $Int, id #C.w!getter.1, getter @l_get : $@convention(thin) (@in C) -> @out Int, setter @l_set : $@convention(thin) (@in Int, @in C) -> ())
%m = keypath $KeyPath<S, () -> ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in S) -> @out @callee_owned (@in ()) -> @out (), setter @m_set : $@convention(thin) (@in @callee_owned (@in ()) -> @out (), @inout S) -> ())
return undef : $()
}
sil @k_id : $@convention(thin) () -> ()
sil @k_get : $@convention(thin) (@in S) -> @out Int
sil @l_get : $@convention(thin) (@in C) -> @out Int
sil @l_set : $@convention(thin) (@in Int, @in C) -> ()
sil @m_get : $@convention(thin) (@in S) -> @out @callee_owned (@in ()) -> @out ()
sil @m_set : $@convention(thin) (@in @callee_owned (@in ()) -> @out (), @inout S) -> ()
struct Gen<T, U> {
var x: T
var y: U
}
struct Foo<T> {
var foo: T
}
// CHECK-LABEL: define{{( protected)?}} swiftcc void @stored_property_generics(%swift.type* %T, %swift.type* %U)
sil @stored_property_generics : $@convention(thin) <T, U> () -> () {
entry:
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: store %swift.type* %T, %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS]])
%i = keypath $KeyPath<Gen<T,T>, T>, <A> (root $Gen<A, A>; stored_property #Gen.x : $A) <T>
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: store %swift.type* %U, %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_J]] to i8*), i8* [[ARGS]])
%j = keypath $KeyPath<Gen<U,U>, U>, <A> (root $Gen<A, A>; stored_property #Gen.y : $A) <U>
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: [[FOO_T:%.*]] = call %swift.type* @_T08keypaths3FooVMa(%swift.type* %T)
// CHECK: store %swift.type* [[FOO_T]], %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS]])
%i2 = keypath $KeyPath<Gen<Foo<T>,Foo<T>>, Foo<T>>, <A> (root $Gen<A, A>; stored_property #Gen.x : $A) <Foo<T>>
return undef : $()
}
// CHECK: define private %swift.type* [[I_GET_GEN_A_A]](i8*)
// CHECK: [[BUF:%.*]] = bitcast i8* %0
// CHECK: [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
// CHECK: [[GEN:%.*]] = call %swift.type* @_T08keypaths3GenVMa(%swift.type* [[A]], %swift.type* [[A]])
// CHECK: ret %swift.type* [[GEN]]
// CHECK: define private %swift.type* [[I_GET_A]](i8*)
// CHECK: [[BUF:%.*]] = bitcast i8* %0
// CHECK: [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
// CHECK: ret %swift.type* [[A]]
// CHECK-LABEL: define{{( protected)?}} swiftcc void @computed_property_generics
sil @computed_property_generics : $@convention(thin) <T, U> () -> () {
entry:
%n = keypath $WritableKeyPath<T, U>, <UUU, TTT> (root $TTT; settable_property $UUU, id @n_get : $@convention(thin) <UU, TT> (@in TT) -> @out UU, getter @n_get : $@convention(thin) <UU, TT> (@in TT) -> @out UU, setter @n_set : $@convention(thin) <UU, TT> (@in UU, @in TT) -> ()) <U, T>
return undef : $()
}
sil @n_get : $@convention(thin) <UU, TT> (@in TT) -> @out UU
sil @n_set : $@convention(thin) <UU, TT> (@in UU, @in 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<S, C>, (
root $S;
settable_property $C,
id @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
getter @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
setter @o_set : $@convention(thin) (@in C, @in S, UnsafeRawPointer) -> (),
indices [%$0 : $C : $C],
indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int
) (%0)
%p = keypath $WritableKeyPath<S, C>, (
root $S;
settable_property $C,
id @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
getter @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
setter @o_set : $@convention(thin) (@in C, @in S, UnsafeRawPointer) -> (),
indices [%$0 : $S : $S, %$1 : $C : $C],
indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int
) (%1, %2)
%r = keypath $WritableKeyPath<S, S>, (
root $S;
settable_property $C,
id @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
getter @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C,
setter @o_set : $@convention(thin) (@in C, @in S, UnsafeRawPointer) -> (),
indices [%$0 : $S : $S, %$1 : $C : $C],
indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int;
settable_property $S,
id @r_get : $@convention(thin) (@in C, UnsafeRawPointer) -> @out S,
getter @r_get : $@convention(thin) (@in C, UnsafeRawPointer) -> @out S,
setter @r_set : $@convention(thin) (@in S, @in C, UnsafeRawPointer) -> (),
indices [%$2 : $S : $S],
indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int
) (%3, %4, %5)
return undef : $()
}
sil @o_get : $@convention(thin) (@in S, UnsafeRawPointer) -> @out C
sil @o_set : $@convention(thin) (@in C, @in S, UnsafeRawPointer) -> ()
sil @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool
sil @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int
sil @r_get : $@convention(thin) (@in C, UnsafeRawPointer) -> @out S
sil @r_set : $@convention(thin) (@in S, @in C, UnsafeRawPointer) -> ()
sil @generic_computed_property_indices : $@convention(thin) <A: Hashable, B: Hashable> (@in A, @in B, @in A, @in B, @in A, @in B) -> () {
entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B):
%s = keypath $WritableKeyPath<A, B>, <X: Hashable, Y: Hashable> (
root $X;
settable_property $Y,
id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in U, @in T, UnsafeRawPointer) -> (),
indices [%$0 : $X : $*X],
indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int
) <A, B> (%0)
%t = keypath $WritableKeyPath<A, B>, <X: Hashable, Y: Hashable> (
root $X;
settable_property $Y,
id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in U, @in T, UnsafeRawPointer) -> (),
indices [%$0 : $Y : $*Y, %$1 : $X : $*X],
indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int
) <A, B> (%1, %2)
%v = keypath $WritableKeyPath<A, A>, <X: Hashable, Y: Hashable> (
root $X;
settable_property $Y,
id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in T, UnsafeRawPointer) -> @out U,
setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in U, @in T, UnsafeRawPointer) -> (),
indices [%$0 : $Y : $*Y, %$1 : $X : $*X],
indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int;
settable_property $X,
id @v_get : $@convention(thin) <T: Hashable, U: Hashable> (@in U, UnsafeRawPointer) -> @out T,
getter @v_get : $@convention(thin) <T: Hashable, U: Hashable> (@in U, UnsafeRawPointer) -> @out T,
setter @v_set : $@convention(thin) <T: Hashable, U: Hashable> (@in T, @in U, UnsafeRawPointer) -> (),
indices [%$2 : $Y : $*Y],
indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int
) <A, B> (%3, %4, %5)
return undef : $()
}
sil @s_get : $@convention(thin) <A: Hashable, B: Hashable> (@in A, UnsafeRawPointer) -> @out B
sil @s_set : $@convention(thin) <A: Hashable, B: Hashable> (@in B, @in A, UnsafeRawPointer) -> ()
sil @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
sil @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int
sil @v_get : $@convention(thin) <A: Hashable, B: Hashable> (@in B, UnsafeRawPointer) -> @out A
sil @v_set : $@convention(thin) <A: Hashable, B: Hashable> (@in A, @in B, UnsafeRawPointer) -> ()