1
+ // RUN: %target-swift-frontend -O -primary-file %s -emit-sil -enable-experimental-distributed | %FileCheck %s --dump-input=fail
2
+
3
+ import _Distributed
4
+
5
+ class SomeClass { }
6
+
7
+ @available ( SwiftStdlib 5 . 5 , * )
8
+ actor SimpleActor {
9
+ let someFieldInLocalActor : SomeClass
10
+ init ( field: SomeClass ) {
11
+ self . someFieldInLocalActor = field
12
+ }
13
+ }
14
+
15
+
16
+ @available ( SwiftStdlib 5 . 5 , * )
17
+ distributed actor SimpleEmptyDistributedActor {
18
+ let localOnlyField : SomeClass
19
+
20
+ init ( field: SomeClass , transport: ActorTransport ) {
21
+ self . localOnlyField = field
22
+ }
23
+ }
24
+
25
+ // ==== ------------------------------------------------------------------------
26
+ // ==== Check that a normal local only actor is left unchanged
27
+
28
+ // CHECK: // SimpleActor.deinit
29
+ // CHECK: sil hidden{{.*}} @$s35distributed_actor_remote_deinit_sil11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject {
30
+ // CHECK: // %0 "self" // users: %6, %5, %2, %1
31
+ // CHECK: bb0(%0 : $SimpleActor):
32
+ // CHECK: debug_value %0 : $SimpleActor, let, name "self", argno 1, implicit // id: %1
33
+ // CHECK: %2 = ref_element_addr %0 : $SimpleActor, #SimpleActor.someFieldInLocalActor // user: %3
34
+ // CHECK: %3 = load %2 : $*SomeClass // user: %4
35
+ // CHECK: strong_release %3 : $SomeClass // id: %4
36
+ // CHECK: %5 = builtin "destroyDefaultActor"(%0 : $SimpleActor) : $()
37
+ // CHECK: %6 = unchecked_ref_cast %0 : $SimpleActor to $Builtin.NativeObject // user: %7
38
+ // CHECK: return %6 : $Builtin.NativeObject // id: %7
39
+ // CHECK: } // end sil function '$s35distributed_actor_remote_deinit_sil11SimpleActorCfd'
40
+
41
+
42
+
43
+
44
+ // ==== deinit must have the extra "if remote..." path emitted for the
45
+ // distributed actor only. That path will not attempt deallocating the
46
+ // `localOnly...` fields, since they were never initialized and have no storage.
47
+
48
+ // CHECK: // SimpleEmptyDistributedActor.deinit
49
+ // sil hidden [available 12.0] @$s35distributed_actor_remote_deinit_sil27SimpleEmptyDistributedActorCfd : $@convention(method) (@guaranteed SimpleEmptyDistributedActor) -> @owned Builtin.NativeObject {
50
+ // CHECK: // [[SELF:%[0-9]+]] "self"
51
+ // CHECK: bb0(%0 : $SimpleEmptyDistributedActor):
52
+ // CHECK: debug_value [[SELF]] : $SimpleEmptyDistributedActor, let, name "self", argno 1, implicit
53
+ // CHECK: [[IDENTITY_ADDR:%[0-9]+]] = ref_element_addr %0 : $SimpleEmptyDistributedActor, #SimpleEmptyDistributedActor.id // users: %13, %24
54
+ // CHECK: [[TRANSPORT_ADDR:%[0-9]+]] = ref_element_addr %0 : $SimpleEmptyDistributedActor, #SimpleEmptyDistributedActor.actorTransport
55
+ // CHECK: [[SELF_1:%[0-9]+]] = init_existential_ref %0 : $SimpleEmptyDistributedActor : $SimpleEmptyDistributedActor, $AnyObject
56
+ // CHECK: // function_ref swift_distributed_actor_is_remote
57
+ // CHECK: [[IS_REMOTE_FN_1:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool
58
+ // CHECK: [[IS_REMOTE_FN_RES_1:%[0-9]+]] = apply [[IS_REMOTE_FN_1]]([[SELF_1]]) : $@convention(thin) (@guaranteed AnyObject) -> Bool
59
+ // CHECK: [[IS_REMOTE_BOOL_1:%[0-9]+]] = struct_extract [[IS_REMOTE_FN_RES_1]] : $Bool, #Bool._value
60
+ // CHECK: cond_br [[IS_REMOTE_BOOL_1]], [[BB_CONT_1:bb[0-9]+]], [[BB_RESIGN_DIST_IDENTITY:bb[0-9]+]]
61
+
62
+ // CHECK: [[BB_CONT_1]]:
63
+ // CHECK: br [[BB_CHECK_REMOTE_OR_LOCAL_MEMBER_DEINIT_TYPE:bb[0-9]+]]
64
+
65
+ // It was a local actor, so we resign the address:
66
+ // CHECK: [[BB_RESIGN_DIST_IDENTITY]]:
67
+ // %11 = open_existential_addr immutable_access %4 : $*ActorTransport to $*@opened({{.*}}) ActorTransport // users: %13, %13, %12
68
+ // CHECK: [[RESIGN_FN:%[0-9]+]] = witness_method $@opened({{.*}}) ActorTransport, #ActorTransport.resignIdentity
69
+ // CHECK: [[RESIGNED:%[0-9]+]] = apply [[RESIGN_FN]]<@opened({{.*}}) ActorTransport>(%3, %11) : $@convention(witness_method: ActorTransport) <τ_0_0 where τ_0_0 : ActorTransport> (@in_guaranteed AnyActorIdentity, @in_guaranteed τ_0_0) -> ()
70
+ // CHECK: br [[BB_CHECK_REMOTE_OR_LOCAL_MEMBER_DEINIT_TYPE]]
71
+
72
+ // Check if we must skip destroying local storage because actor was remote
73
+ // CHECK: [[BB_CHECK_REMOTE_OR_LOCAL_MEMBER_DEINIT_TYPE]]:
74
+ // CHECK: %15 = init_existential_ref %0 : $SimpleEmptyDistributedActor : $SimpleEmptyDistributedActor, $AnyObject
75
+ // CHECK: %16 = apply %6(%15) : $@convention(thin) (@guaranteed AnyObject) -> Bool
76
+ // CHECK: %17 = struct_extract %16 : $Bool, #Bool._value // user: %18
77
+ // CHECK: cond_br %17, [[BB_CONT_REMOTE_DONT_DESTROY_LOCAL_MEMBERS:bb[0-9]+]], [[BB_CONT_DESTROY_LOCAL_THEN_INDEPENDENT_MEMBERS:bb[0-9]+]]
78
+
79
+ // CHECK: [[BB_CONT_REMOTE_DONT_DESTROY_LOCAL_MEMBERS]]:
80
+ // CHECK: br [[BB_DESTROY_INDEPENDENT_MEMBERS:bb[0-9]+]]
81
+
82
+ // We were a local instance after all, and thus must destroy local properties
83
+ // CHECK: [[BB_CONT_DESTROY_LOCAL_THEN_INDEPENDENT_MEMBERS]]:
84
+ // CHECK: [[FIELD_ADDR:%[0-9]+]] = ref_element_addr %0 : $SimpleEmptyDistributedActor, #SimpleEmptyDistributedActor.localOnlyField
85
+ // CHECK: [[LOAD_FIELD_ADDR:%[0-9]+]] = load [[FIELD_ADDR]] : $*SomeClass
86
+ // CHECK: strong_release [[LOAD_FIELD_ADDR]] : $SomeClass
87
+ // CHECK: br [[BB_DESTROY_INDEPENDENT_MEMBERS]]
88
+
89
+ // Destroy "distributed nonisolated" fields and the actor itself
90
+ // CHECK: [[BB_DESTROY_INDEPENDENT_MEMBERS]]:
91
+ // CHECK: destroy_addr [[IDENTITY_ADDR]] : $*AnyActorIdentity
92
+ // CHECK: destroy_addr [[TRANSPORT_ADDR]] : $*ActorTransport
93
+ // CHECK: {{.*}} = builtin "destroyDefaultActor"(%0 : $SimpleEmptyDistributedActor) : $()
94
+ // CHECK: dealloc_ref [[SELF]] : $SimpleEmptyDistributedActor
95
+ // CHECK: [[EMPTY:%[0-9]+]] = tuple ()
96
+ // CHECK: return [[EMPTY]] : $()
97
+ // } // end sil function '$s35distributed_actor_remote_deinit_sil27SimpleEmptyDistributedActorCfD'
0 commit comments