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