File: transfernonsendable.sil

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (416 lines) | stat: -rw-r--r-- 23,404 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
// RUN: %target-sil-opt -transfer-non-sendable -strict-concurrency=complete %s -o /dev/null -verify

// REQUIRES: concurrency
// REQUIRES: asserts

// PLEASE READ THIS!
//
// This test is specifically meant for small test cases that come from bugs that
// do not categorize by a specific category. If this gets too big, please split
// sections of tests out if possible.

sil_stage raw

import Swift
import Builtin
import _Concurrency

////////////////////////
// MARK: Declarations //
////////////////////////

class Klass {}

class NonSendableKlass {
  var klass: Klass

  func asyncCall() async
}

sil @transferNonSendableKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
sil @useNonSendableKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
sil @constructNonSendableKlass : $@convention(thin) () -> @owned NonSendableKlass
sil @useUnmanagedNonSendableKlass : $@convention(thin) (@guaranteed @sil_unmanaged NonSendableKlass) -> ()

final class SendableKlass : Sendable {}

sil @transferSendableKlass : $@convention(thin) @async (@guaranteed SendableKlass) -> ()
sil @constructSendableKlass : $@convention(thin) () -> @owned SendableKlass

final class KlassContainingKlasses {
  let nsImmutable : NonSendableKlass
  var nsMutable : NonSendableKlass
  let sImmutable : SendableKlass
  var sMutable : SendableKlass
}

sil @transferKlassContainingKlasses : $@convention(thin) @async (@guaranteed KlassContainingKlasses) -> ()
sil @useKlassContainingKlasses : $@convention(thin) (@guaranteed KlassContainingKlasses) -> ()
sil @constructKlassContainingKlasses : $@convention(thin) () -> @owned KlassContainingKlasses

@_moveOnly
struct NonSendableMoveOnlyStruct {
  var ns: NonSendableKlass

  deinit
}

sil @constructMoveOnlyStruct : $@convention(thin) () -> @owned NonSendableMoveOnlyStruct
sil @transferMoveOnlyStruct : $@convention(thin) @async (@guaranteed NonSendableMoveOnlyStruct) -> ()

struct NonSendableStruct {
  var ns: NonSendableKlass
}

sil @constructStruct : $@convention(thin) () -> @owned NonSendableStruct
sil @transferStruct : $@convention(thin) @async (@guaranteed NonSendableStruct) -> ()

sil @transferRawPointer : $@convention(thin) @async (Builtin.RawPointer) -> ()
sil @useRawPointer : $@convention(thin) (Builtin.RawPointer) -> ()
sil @initRawPointer : $@convention(thin) () -> Builtin.RawPointer

sil @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
sil @transferIndirectWithOutResult : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
sil @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
sil @initIndirect : $@convention(thin) <T> () -> @out T
sil @initIndirectTransferring : $@convention(thin) @async <T> () -> @out T
sil @initIndirectTransferringError : $@convention(thin) @async <T> () -> (@out Optional<T>, @error any Error)

enum FakeOptional<T> {
case none
case some(T)
}

sil @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
sil @swift_asyncLet_finish : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()

@MainActor
struct MainActorIsolatedStruct {
  let ns: NonSendableKlass
}

@MainActor
enum MainActorIsolatedEnum {
  case first
  case second(NonSendableKlass)
}

actor MyActor {
  var klass: NonSendableKlass { get set }
}

sil @beginApplyMultipleResultCallee : $@yield_once @convention(thin) () -> (@yields @guaranteed NonSendableKlass, @yields @guaranteed NonSendableKlass)

/////////////////
// MARK: Tests //
/////////////////

// This goes through the access projection code differently from normal
// project_box since we do not see the alloc_box.
sil [ossa] @project_box_loadable_test_case : $@convention(thin) @async (@in { var NonSendableKlass }) -> () {
bb0(%0 : $*{ var NonSendableKlass }):
  %1 = load [take] %0 : $*{ var NonSendableKlass }
  %3 = project_box %1 : ${ var NonSendableKlass }, 0

  %f = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%3) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  // expected-warning @-1 {{}}
  destroy_value %1 : ${ var NonSendableKlass }

  %9999 = tuple ()
  return %9999 : $()
}

// This doesn't error since the @out parameter is not transferred when it is initialized.
//
// DISCUSSION: The frontend prevents us from using such a value. But we
// shouldn't crash on such values.
sil [ossa] @transfer_does_not_transfer_out_parameters_1 : $@convention(thin) @async () -> () {
bb0:
  %0 = alloc_stack $NonSendableKlass
  %init = function_ref @initIndirect : $@convention(thin) <T> () -> @out T
  apply %init<NonSendableKlass>(%0) : $@convention(thin) <T> () -> @out T

  %1 = alloc_stack $NonSendableKlass
  %f = function_ref @transferIndirectWithOutResult : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0

  %useIndirect = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  apply %useIndirect<NonSendableKlass>(%1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()

  destroy_addr %1 : $*NonSendableKlass
  dealloc_stack %1 : $*NonSendableKlass
  destroy_addr %0 : $*NonSendableKlass
  dealloc_stack %0 : $*NonSendableKlass

  %9999 = tuple ()
  return %9999 : $()
}

sil [ossa] @transfer_does_not_transfer_out_parameters_2 : $@convention(thin) @async () -> () {
bb0:
  %0 = alloc_stack $NonSendableKlass
  %init = function_ref @initIndirect : $@convention(thin) <T> () -> @out T
  apply %init<NonSendableKlass>(%0) : $@convention(thin) <T> () -> @out T

  %1 = alloc_stack $NonSendableKlass
  %f = function_ref @transferIndirectWithOutResult : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0

  %f2 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f2<NonSendableKlass>(%1) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  // expected-warning @-1 {{}}
  %useIndirect = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  apply %useIndirect<NonSendableKlass>(%1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  // expected-note @-1 {{access can happen concurrently}}

  destroy_addr %1 : $*NonSendableKlass
  dealloc_stack %1 : $*NonSendableKlass
  destroy_addr %0 : $*NonSendableKlass
  dealloc_stack %0 : $*NonSendableKlass

  %9999 = tuple ()
  return %9999 : $()
}

sil @implicitClosure : $@convention(thin) @Sendable @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass>

sil [ossa] @asyncLetWithThinToThickFunction : $@convention(thin) @async () -> () {
bb0:
  %0 = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
  hop_to_executor %0 : $Optional<Builtin.Executor>
  %2 = alloc_stack $NonSendableKlass
  %3 = address_to_pointer %2 : $*NonSendableKlass to $Builtin.RawPointer
  %4 = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
  %5 = function_ref @implicitClosure : $@convention(thin) @Sendable @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass>
  %6 = convert_function %5 : $@convention(thin) @Sendable @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass> to $@convention(thin) @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass>
  %7 = thin_to_thick_function %6 : $@convention(thin) @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass> to $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass>
  %8 = builtin "startAsyncLetWithLocalBuffer"<NonSendableKlass>(%4 : $Optional<Builtin.RawPointer>, %7 : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <NonSendableKlass>, %3 : $Builtin.RawPointer) : $Builtin.RawPointer
  %9 = function_ref @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %10 = apply %9(%8, %3) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  hop_to_executor %0 : $Optional<Builtin.Executor>
  %12 = load [copy] %2 : $*NonSendableKlass
  destroy_value %12 : $NonSendableKlass
  %14 = function_ref @swift_asyncLet_finish : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %15 = apply %14(%8, %3) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  hop_to_executor %0 : $Optional<Builtin.Executor>
  %17 = builtin "endAsyncLetLifetime"(%8 : $Builtin.RawPointer) : $()
  dealloc_stack %2 : $*NonSendableKlass
  %19 = tuple ()
  return %19 : $()
}

// Dead block crasher
//
// We used to crash here since we attempted to process /all/ blocks for
// diagnostic even for non-dead blocks. This is a problem since the dataflow
// uses a reverse post order traversal to get quick convergence and that skips
// dead blocks.
sil [ossa] @dead_block_crasher : $@convention(thin) @async () -> () {
bb0:
  %0 = function_ref @constructNonSendableKlass : $@convention(thin) () -> @owned NonSendableKlass
  %1 = apply %0() : $@convention(thin) () -> @owned NonSendableKlass
  br bb1

bbDeadBlock:
  %transfer = function_ref @transferNonSendableKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %transfer(%1) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
  br bb1

bb1:
  destroy_value %1 : $NonSendableKlass
  %9999 = tuple ()
  return %9999 : $()
}

sil [ossa] @synchronous_returns_transferring : $@convention(method) (@guaranteed NonSendableStruct) -> @sil_sending @owned NonSendableKlass {
bb0(%0 : @guaranteed $NonSendableStruct):
  debug_value %0 : $NonSendableStruct, var, name "myname"
  %2 = struct_extract %0 : $NonSendableStruct, #NonSendableStruct.ns
  %3 = copy_value %2 : $NonSendableKlass
  return %3 : $NonSendableKlass // expected-warning {{sending 'myname.ns' risks causing data races}}
  // expected-note @-1 {{task-isolated 'myname.ns' cannot be a 'sending' result. task-isolated uses may race with caller uses}}
}

sil [ossa] @synchronous_returns_transferring_globalactor_struct_structextract : $@convention(method) (@guaranteed MainActorIsolatedStruct) -> @sil_sending @owned NonSendableKlass {
bb0(%0 : @guaranteed $MainActorIsolatedStruct):
  debug_value %0 : $MainActorIsolatedStruct, var, name "myname"
  %2 = struct_extract %0 : $MainActorIsolatedStruct, #MainActorIsolatedStruct.ns
  %3 = copy_value %2 : $NonSendableKlass
  return %3 : $NonSendableKlass // expected-warning {{sending 'myname.ns' risks causing data races}}
  // expected-note @-1 {{main actor-isolated 'myname.ns' cannot be a 'sending' result. main actor-isolated uses may race with caller uses}}
}

sil [ossa] @synchronous_returns_transferring_globalactor_struct_structelementaddr : $@convention(method) (@in_guaranteed MainActorIsolatedStruct) -> @sil_sending @owned NonSendableKlass {
bb0(%0 : $*MainActorIsolatedStruct):
  debug_value %0 : $*MainActorIsolatedStruct, var, name "myname"
  %2 = struct_element_addr %0 : $*MainActorIsolatedStruct, #MainActorIsolatedStruct.ns
  %3 = load [copy] %2 : $*NonSendableKlass
  return %3 : $NonSendableKlass // expected-warning {{sending 'myname.ns' risks causing data races}}
  // expected-note @-1 {{main actor-isolated 'myname.ns' cannot be a 'sending' result. main actor-isolated uses may race with caller uses}}
}

sil [ossa] @synchronous_returns_transferring_globalactor_enum_uncheckedenumdata : $@convention(method) (@guaranteed MainActorIsolatedEnum) -> @sil_sending @owned NonSendableKlass {
bb0(%0 : @guaranteed $MainActorIsolatedEnum):
  debug_value %0 : $MainActorIsolatedEnum, var, name "myname"
  %2 = unchecked_enum_data %0 : $MainActorIsolatedEnum, #MainActorIsolatedEnum.second!enumelt
  %3 = copy_value %2 : $NonSendableKlass
  return %3 : $NonSendableKlass // expected-warning {{sending 'myname.second' risks causing data races}}
  // expected-note @-1 {{main actor-isolated 'myname.second' cannot be a 'sending' result. main actor-isolated uses may race with caller uses}}
}

sil [ossa] @synchronous_returns_transferring_globalactor_enum_uncheckedtakeenumdataaddr : $@convention(method) (@in MainActorIsolatedEnum) -> @sil_sending @owned NonSendableKlass {
bb0(%0 : $*MainActorIsolatedEnum):
  debug_value %0 : $*MainActorIsolatedEnum, var, name "myname"
  %2 = unchecked_take_enum_data_addr %0 : $*MainActorIsolatedEnum, #MainActorIsolatedEnum.second!enumelt
  %3 = load [take] %2 : $*NonSendableKlass
  return %3 : $NonSendableKlass // expected-warning {{sending 'myname.second' risks causing data races}}
  // expected-note @-1 {{main actor-isolated 'myname.second' cannot be a 'sending' result. main actor-isolated uses may race with caller uses}}
}

sil [ossa] @synchronous_returns_transferring_globalactor_enum_switchenum : $@convention(method) (@guaranteed MainActorIsolatedEnum) -> @sil_sending @owned FakeOptional<NonSendableKlass> {
bb0(%0 : @guaranteed $MainActorIsolatedEnum):
  debug_value %0 : $MainActorIsolatedEnum, var, name "myname"
  switch_enum %0 : $MainActorIsolatedEnum, case #MainActorIsolatedEnum.first!enumelt: bb1, case #MainActorIsolatedEnum.second!enumelt: bb2

bb1:
  %nil = enum $FakeOptional<NonSendableKlass>, #FakeOptional.none!enumelt
  br bb3(%nil : $FakeOptional<NonSendableKlass>)

bb2(%1 : @guaranteed $NonSendableKlass):
  %2 = copy_value %1 : $NonSendableKlass
  %3 = enum $FakeOptional<NonSendableKlass>, #FakeOptional.some!enumelt, %2 : $NonSendableKlass
  br bb3(%3 : $FakeOptional<NonSendableKlass>)

bb3(%4 : @owned $FakeOptional<NonSendableKlass>):
  return %4 : $FakeOptional<NonSendableKlass> // expected-warning {{sending 'myname.some' risks causing data races}}
  // expected-note @-1 {{main actor-isolated 'myname.some' cannot be a 'sending' result. main actor-isolated uses may race with caller uses}}
}

sil [ossa] @warningIfCallingGetter : $@convention(method) @async (@sil_isolated @guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
  debug_value %0 : $MyActor, let, name "self", argno 1
  hop_to_executor %0 : $MyActor
  %3 = class_method %0 : $MyActor, #MyActor.klass!getter : (isolated MyActor) -> () -> NonSendableKlass, $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
  %4 = apply %3(%0) : $@convention(method) (@sil_isolated @guaranteed MyActor) -> @owned NonSendableKlass
  %5 = class_method %4 : $NonSendableKlass, #NonSendableKlass.asyncCall : (NonSendableKlass) -> () async -> (), $@convention(method) @async (@guaranteed NonSendableKlass) -> ()
  %6 = apply [caller_isolation=nonisolated] [callee_isolation=actor_instance] %5(%4) : $@convention(method) @async (@guaranteed NonSendableKlass) -> () // expected-warning {{}}
  destroy_value %4 : $NonSendableKlass
  hop_to_executor %0 : $MyActor
  %9 = tuple ()
  return %9 : $()
}

sil [ossa] @assignIntoSetter : $@convention(method) @async (@sil_isolated @guaranteed MyActor) -> () {
bb0(%0 : @guaranteed $MyActor):
  debug_value %0 : $MyActor, let, name "self", argno 1
  hop_to_executor %0 : $MyActor
  %4 = function_ref @constructNonSendableKlass : $@convention(thin) () -> @owned NonSendableKlass
  %5 = apply %4() : $@convention(thin) () -> @owned NonSendableKlass
  %6 = move_value [lexical] [var_decl] %5 : $NonSendableKlass
  debug_value %6 : $NonSendableKlass, let, name "x"
  %8 = copy_value %6 : $NonSendableKlass
  %9 = class_method %0 : $MyActor, #MyActor.klass!setter : (isolated MyActor) -> (NonSendableKlass) -> (), $@convention(method) (@owned NonSendableKlass, @sil_isolated @guaranteed MyActor) -> ()
  %10 = apply %9(%8, %0) : $@convention(method) (@owned NonSendableKlass, @sil_isolated @guaranteed MyActor) -> ()
  %11 = alloc_stack $NonSendableKlass
  %12 = store_borrow %6 to %11 : $*NonSendableKlass
  %13 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  %14 = apply [caller_isolation=actor_instance] [callee_isolation=global_actor] %13<NonSendableKlass>(%12) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> () // expected-warning {{}}
  end_borrow %12 : $*NonSendableKlass
  dealloc_stack %11 : $*NonSendableKlass
  hop_to_executor %0 : $MyActor
  destroy_value %6 : $NonSendableKlass
  %19 = tuple ()
  return %19 : $()
}

sil @sendableAsyncLetClosure : $@convention(thin) @Sendable @async @substituted <τ_0_0> (@guaranteed NonSendableKlass) -> (@out τ_0_0, @error any Error) for <Int>

sil [ossa] @sendableAsyncLetClosureTest : $@convention(thin) @async () -> () {
bb0:
  %3 = function_ref @constructNonSendableKlass : $@convention(thin) () -> @owned NonSendableKlass
  %4 = apply %3() : $@convention(thin) () -> @owned NonSendableKlass
  %5 = move_value [lexical] [var_decl] %4 : $NonSendableKlass
  debug_value %5 : $NonSendableKlass, let, name "x"
  %7 = alloc_stack $Int
  %8 = address_to_pointer %7 : $*Int to $Builtin.RawPointer
  %9 = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
  %10 = function_ref @sendableAsyncLetClosure : $@convention(thin) @Sendable @async @substituted <τ_0_0> (@guaranteed NonSendableKlass) -> (@out τ_0_0, @error any Error) for <Int>
  %11 = copy_value %5 : $NonSendableKlass
  %12 = partial_apply [callee_guaranteed] %10(%11) : $@convention(thin) @Sendable @async @substituted <τ_0_0> (@guaranteed NonSendableKlass) -> (@out τ_0_0, @error any Error) for <Int>
  %13 = convert_function %12 : $@Sendable @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int> to $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
  %14 = convert_escape_to_noescape [not_guaranteed] %13 : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int> to $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
  %15 = builtin "startAsyncLetWithLocalBuffer"<Int>(%9 : $Optional<Builtin.RawPointer>, %14 : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>, %8 : $Builtin.RawPointer) : $Builtin.RawPointer

  %useValue = function_ref @useNonSendableKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
  apply %useValue(%5) : $@convention(thin) (@guaranteed NonSendableKlass) -> ()

  %26 = function_ref @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %27 = apply %26(%15, %8) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %29 = load [trivial] %7 : $*Int
  %30 = function_ref @swift_asyncLet_finish : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %31 = apply %30(%15, %8) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
  %33 = builtin "endAsyncLetLifetime"(%15 : $Builtin.RawPointer) : $()
  destroy_value %14 : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
  destroy_value %13 : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <Int>
  dealloc_stack %7 : $*Int
  destroy_value %5 : $NonSendableKlass
  %38 = tuple ()
  return %38 : $()
}

// Make sure that when we process the following sil we do not crash.
//
// We previously crashed since we used the base of the storage instead of the
// operand of the root (the ref_element_addr)
sil [ossa] @test_ref_element_addr_with_different_storage_no_crash : $@convention(method) <Self where Self : NonSendableKlass> (@guaranteed Self) -> () {
bb0(%0 : @guaranteed $Self):
  %1 = copy_value %0 : $Self
  %2 = upcast %1 : $Self to $NonSendableKlass
  %3 = begin_borrow %2 : $NonSendableKlass
  %4 = ref_element_addr [immutable] %3 : $NonSendableKlass, #NonSendableKlass.klass
  %5 = load [copy] %4 : $*Klass
  destroy_value %5 : $Klass
  end_borrow %3 : $NonSendableKlass
  destroy_value %2 : $NonSendableKlass
  %9999 = tuple ()
  return %9999 : $()
}

sil @closureForCheckedContinuation : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
sil @withCheckedContinuation : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0

// We shouldn't emit any error here due to sil_sending.
sil [ossa] @sending_result_from_callee : $@convention(thin) @async () -> () {
bb0:
  %0 = alloc_stack $NonSendableKlass
  %1 = function_ref @closureForCheckedContinuation : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
  %1a = thin_to_thick_function %1 : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()  to $@noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
  %2 = enum $Optional<any Actor>, #Optional.none!enumelt
  %3 = function_ref @withCheckedContinuation : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0
  apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %3<NonSendableKlass>(%0, %2, %1a) : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0

  %f = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
  apply [caller_isolation=nonisolated] [callee_isolation=actor_instance] %f<NonSendableKlass>(%0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()

  destroy_addr %0 : $*NonSendableKlass
  dealloc_stack %0 : $*NonSendableKlass
  %9999 = tuple ()
  return %9999 : $()
}

// Make sure that we do not crash on this.
//
// We used to crash on this since we would want to assign the region of an
// operand to the results... but we do not have one and have multiple
// results. This doesn't normally happen with most applies since applies do not
// have multiple results, so in such a case, we would just assign fresh and not
// try to do the assignment for the rest of the values.
sil [ossa] @handleNoOperandToAssignToResults : $@convention(thin) () -> () {
bb0:
  %0 = function_ref @beginApplyMultipleResultCallee : $@yield_once @convention(thin) () -> (@yields @guaranteed NonSendableKlass, @yields @guaranteed NonSendableKlass)
  (%1, %2, %3) = begin_apply %0() : $@yield_once @convention(thin) () -> (@yields @guaranteed NonSendableKlass, @yields @guaranteed NonSendableKlass)
  end_apply %3
  %9999 = tuple ()
  return %9999 : $()
}