4
4
// REQUIRES: concurrency
5
5
// REQUIRES: distributed
6
6
7
+ // This test checks that we resign the identity for local deallocations,
8
+ // destroy only the correct stored properties whether remote or local, and also
9
+ // destroy the executor. It checks that remote actor proxies are not isolated.
10
+ // Additionally, we add basic coverage for a non-distributed actor's deinit.
11
+
7
12
import Distributed
8
13
import FakeDistributedActorSystems
9
14
10
15
typealias DefaultDistributedActorSystem = FakeActorSystem
11
16
12
17
final class SomeClass : Sendable { }
13
18
19
+ @inline ( never)
20
+ private nonisolated func doIt( ) { }
21
+
22
+ // MARK: - Distributed actor with nonisolated deinit
23
+
14
24
distributed actor MyDistActor {
15
25
let localOnlyField : SomeClass
16
26
@@ -20,7 +30,7 @@ distributed actor MyDistActor {
20
30
}
21
31
}
22
32
23
- // MARK: distributed actor check
33
+ // MARK: Destroying deinit
24
34
25
35
// CHECK-LABEL: // MyDistActor.deinit
26
36
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject {
@@ -59,6 +69,14 @@ distributed actor MyDistActor {
59
69
60
70
// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfd'
61
71
72
+ // MARK: Isolated deallocating deinit
73
+
74
+ // ===== -----------------------------------------------------------------------
75
+ // CHECK-NOT: MyDistActor.__isolated_deallocating_deinit
76
+ // CHECK-NOT: @$s14default_deinit11MyDistActorCfZ
77
+
78
+ // MARK: Deallocating deinit
79
+
62
80
// ===== -----------------------------------------------------------------------
63
81
// CHECK-LABEL: MyDistActor.__deallocating_deinit
64
82
// CHECK-NEXT: sil hidden @$s14default_deinit11MyDistActorCfD : $@convention(method) (@owned MyDistActor) -> () {
@@ -113,12 +131,133 @@ distributed actor MyDistActor {
113
131
114
132
// ===== -----------------------------------------------------------------------
115
133
134
+ // MARK: - Distributed actor with isolated deinit
116
135
117
- // This test checks that we resign the identity for local deallocations,
118
- // destroy only the correct stored properties whether remote or local, and also
119
- // destroy the executor.
136
+ distributed actor MyDistActorIsolated {
137
+ let localOnlyField : SomeClass
138
+
139
+ init ( system: FakeActorSystem ) {
140
+ self . actorSystem = system
141
+ self . localOnlyField = SomeClass ( )
142
+ }
143
+
144
+ deinit {
145
+ doIt ( )
146
+ }
147
+ }
148
+
149
+ // MARK: Destroying deinit
150
+
151
+ // CHECK-LABEL: // MyDistActorIsolated.deinit
152
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject {
153
+ // CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
154
+
155
+ // Resign the ID by calling actorSystem.resignID, before we destroy properties:
156
+ // CHECK: [[ID_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
157
+ // CHECK: [[SYS_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
158
+ // CHECK: [[ID_LOAD:%[0-9]+]] = load [[ID_REF]] : $*ActorAddress
159
+ // CHECK: [[SYS_LOAD:%[0-9]+]] = load [[SYS_REF]] : $*FakeActorSystem
160
+ // CHECK: [[FN_REF:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8resignIDyyAA0C7AddressVF : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> ()
161
+ // CHECK: [[DROP:%[0-9]+]] = apply [[FN_REF]]([[ID_LOAD]], [[SYS_LOAD]]) : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> ()
162
+ // CHECK: [[DROP:%[0-9]+]] = tuple ()
163
+
164
+ // Destroy implicit Distributed Actor field: id
165
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
166
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress
167
+ // CHECK: destroy_addr [[ACCESS]] : $*ActorAddress
168
+ // CHECK: end_access [[ACCESS]] : $*ActorAddress
169
+
170
+ // Destroy implicit Distributed Actor field: actorSystem
171
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
172
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem
173
+ // CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem
174
+ // CHECK: end_access [[ACCESS]] : $*FakeActorSystem
175
+
176
+ // Destroy local fields:
177
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.localOnlyField
178
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*SomeClass
179
+ // CHECK: destroy_addr [[ACCESS]] : $*SomeClass
180
+ // CHECK: end_access [[ACCESS]] : $*SomeClass
181
+
182
+ // CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $()
183
+ // CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] : $MyDistActorIsolated to $Builtin.NativeObject
184
+ // CHECK: return [[CAST]] : $Builtin.NativeObject
185
+
186
+ // CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfd'
187
+
188
+ // MARK: Isolated deallocating deinit
189
+
190
+ // ===== -----------------------------------------------------------------------
191
+ // CHECK-LABEL: MyDistActorIsolated.__isolated_deallocating_deinit
192
+ // CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> () {
193
+ // CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
194
+ // CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject
195
+ // CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject
196
+ // CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $MyDistActorIsolated
197
+ // CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $MyDistActorIsolated
198
+ // CHECK: [[RESULT:%[0-9]+]] = tuple ()
199
+ // CHECK: return [[RESULT]] : $()
200
+ // CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfZ'
201
+
202
+ // MARK: Deallocating deinit
203
+
204
+ // ===== -----------------------------------------------------------------------
205
+ // CHECK-LABEL: MyDistActorIsolated.__deallocating_deinit
206
+ // CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfD : $@convention(method) (@owned MyDistActorIsolated) -> () {
207
+ // CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
208
+ // CHECK: [[EXI_SELF:%[0-9]+]] = init_existential_ref [[SELF]] : $MyDistActorIsolated : $MyDistActorIsolated, $AnyObject
209
+ // CHECK: [[IS_REMOTE_FN:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool
210
+ // CHECK: [[IS_REMOTE:%[0-9]+]] = apply [[IS_REMOTE_FN]]([[EXI_SELF]])
211
+ // CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[IS_REMOTE]] : $Bool, #Bool._value
212
+ // CHECK: cond_br [[RAW_BOOL]], [[REMOTE_ACTOR_DEINIT_BB:bb[0-9]+]], [[LOCAL_ACTOR_DEINIT_BB:bb[0-9]+]]
213
+
214
+ // ===== -----------------------------------------------------------------------
215
+ // CHECK: // localActorDeinitBB
216
+ // CHECK: [[LOCAL_ACTOR_DEINIT_BB]]:
217
+ // CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> ()
218
+ // CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $MyDistActorIsolated
219
+ // CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_performOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
220
+ // CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $MyDistActorIsolated to $AnyObject
221
+ // CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned MyDistActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> ()
222
+ // CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
223
+ // CHECK: br [[FINISH_DEINIT_BB:bb[0-9]+]]
224
+
225
+ // ===== -----------------------------------------------------------------------
226
+ // CHECK: // finishDeinitBB
227
+ // CHECK: [[FINISH_DEINIT_BB]]:
228
+ // CHECK: [[RESULT:%[0-9]+]] = tuple ()
229
+ // CHECK: return [[RESULT]] : $()
120
230
121
- // MARK: local actor check
231
+ // ===== -----------------------------------------------------------------------
232
+ // CHECK: // remoteActorDeinitBB
233
+ // CHECK: [[REMOTE_ACTOR_DEINIT_BB]]:
234
+
235
+ // Even just the remote deinit branch must destroy the ID
236
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
237
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress
238
+ // CHECK: destroy_addr [[ACCESS]] : $*ActorAddress
239
+ // CHECK: end_access [[ACCESS]] : $*ActorAddress
240
+
241
+ // As well as the actor system:
242
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
243
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem
244
+ // CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem
245
+ // CHECK: end_access [[ACCESS]] : $*FakeActorSystem
246
+
247
+ // Destroy default actor implementation
248
+ // CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $()
249
+
250
+ // And deallocate the proxy
251
+ // CHECK: dealloc_ref [[SELF]] : $MyDistActorIsolated
252
+
253
+ // Return
254
+ // CHECK: br [[FINISH_DEINIT_BB]]
255
+
256
+ // CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfD'
257
+
258
+ // ===== -----------------------------------------------------------------------
259
+
260
+ // MARK: - Local actor with nonisolated deinit
122
261
123
262
@available ( macOS 12 , * )
124
263
actor SimpleActor {
@@ -128,9 +267,11 @@ actor SimpleActor {
128
267
}
129
268
}
130
269
131
- // additionally, we add basic coverage for a non-distributed actor's deinit
270
+ // MARK: Destroying deinit
132
271
133
- // CHECK-LABEL: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject {
272
+ // ===== -----------------------------------------------------------------------
273
+ // CHECK-LABEL: // SimpleActor.deinit
274
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject {
134
275
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor):
135
276
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActor, #SimpleActor.someField
136
277
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]]
@@ -140,3 +281,81 @@ actor SimpleActor {
140
281
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]]
141
282
// CHECK: return [[CAST]] : $Builtin.NativeObject
142
283
// CHECK: } // end sil function '$s14default_deinit11SimpleActorCfd'
284
+
285
+ // MARK: Isolated deallocating deinit
286
+
287
+ // ===== -----------------------------------------------------------------------
288
+ // CHECK-NOT: SimpleActor.__isolated_deallocating_deinit
289
+ // CHECK-NOT: @$s14default_deinit11SimpleActorCfZ
290
+
291
+ // MARK: Deallocating deinit
292
+
293
+ // ===== -----------------------------------------------------------------------
294
+ // CHECK-LABEL: // SimpleActor.__deallocating_deinit
295
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfD : $@convention(method) (@owned SimpleActor) -> () {
296
+ // CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor):
297
+ // CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject
298
+ // CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject
299
+ // CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActor
300
+ // CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActor
301
+ // CHECK: [[RESULT:%[0-9]+]] = tuple ()
302
+ // CHECK: return [[RESULT]] : $()
303
+ // CHECK: } // end sil function '$s14default_deinit11SimpleActorCfD'
304
+
305
+ // MARK: - Local actor with nonisolated deinit
306
+
307
+ @available ( macOS 12 , * )
308
+ actor SimpleActorIsolated {
309
+ let someField : SomeClass
310
+ init ( ) {
311
+ self . someField = SomeClass ( )
312
+ }
313
+ deinit {
314
+ doIt ( )
315
+ }
316
+ }
317
+
318
+ // MARK: Destroying deinit
319
+
320
+ // ===== -----------------------------------------------------------------------
321
+ // CHECK-LABEL: // SimpleActorIsolated.deinit
322
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject {
323
+ // CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
324
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActorIsolated, #SimpleActorIsolated.someField
325
+ // CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]]
326
+ // CHECK: destroy_addr [[ACCESS]] : $*SomeClass
327
+ // CHECK: end_access [[ACCESS]]
328
+ // CHECK: builtin "destroyDefaultActor"([[SELF]] : $SimpleActorIsolated)
329
+ // CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]]
330
+ // CHECK: return [[CAST]] : $Builtin.NativeObject
331
+ // CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfd'
332
+
333
+ // MARK: Isolated deallocating deinit
334
+
335
+ // ===== -----------------------------------------------------------------------
336
+ // CHECK-LABEL: // SimpleActorIsolated.__isolated_deallocating_deinit
337
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> () {
338
+ // CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
339
+ // CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject
340
+ // CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject
341
+ // CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActorIsolated
342
+ // CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActorIsolated
343
+ // CHECK: [[RESULT:%[0-9]+]] = tuple ()
344
+ // CHECK: return [[RESULT]] : $()
345
+ // CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfZ'
346
+
347
+ // MARK: Deallocating deinit
348
+
349
+ // ===== -----------------------------------------------------------------------
350
+ // CHECK-LABEL: // SimpleActorIsolated.__deallocating_deinit
351
+ // CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfD : $@convention(method) (@owned SimpleActorIsolated) -> () {
352
+ // CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
353
+ // CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> ()
354
+ // CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $SimpleActorIsolated
355
+ // CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_performOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
356
+ // CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $SimpleActorIsolated to $AnyObject
357
+ // CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned SimpleActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> ()
358
+ // CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
359
+ // CHECK: [[RESULT:%[0-9]+]] = tuple ()
360
+ // CHECK: return [[RESULT]] : $()
361
+ // CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfD'
0 commit comments