@@ -270,9 +270,9 @@ struct BlueActor {
270
270
// CHECK: [[R:%[0-9]+]] = apply [[GETTER]]([[REDMT]]) : $@convention(method) (@thin RedActor.Type) -> @owned RedActorImpl
271
271
// CHECK: [[REDEXE:%[0-9]+]] = begin_borrow [[R]] : $RedActorImpl
272
272
// CHECK: hop_to_executor [[REDEXE]] : $RedActorImpl
273
+ // CHECK-NEXT: end_borrow [[REDEXE]]
273
274
// ---- now invoke redFn, hop back to Blue, and clean-up ----
274
275
// CHECK-NEXT: {{%[0-9]+}} = apply [[CALLEE]]([[ARG]]) : $@convention(thin) (Int) -> ()
275
- // CHECK-NEXT: end_borrow [[REDEXE]] : $RedActorImpl
276
276
// CHECK-NEXT: destroy_value [[R]] : $RedActorImpl
277
277
// CHECK-NEXT: hop_to_executor [[BLUEEXE]] : $BlueActorImpl
278
278
// CHECK: end_borrow [[BLUEEXE]] : $BlueActorImpl
@@ -287,8 +287,8 @@ struct BlueActor {
287
287
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] :
288
288
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $RedActorImpl
289
289
// CHECK-NEXT: hop_to_executor [[BORROW]] : $RedActorImpl
290
- // CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
291
290
// CHECK-NEXT: end_borrow [[BORROW]] : $RedActorImpl
291
+ // CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
292
292
// CHECK-NEXT: destroy_value
293
293
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]]
294
294
// CHECK: } // end sil function '$s4test20unspecifiedAsyncFuncyyYaF'
@@ -315,6 +315,7 @@ func anotherUnspecifiedAsyncFunc(_ red : RedActorImpl) async {
315
315
// CHECK: hop_to_executor [[GENERIC_EXEC]] :
316
316
// CHECK: function_ref @$s4test8RedActorV6sharedAA0bC4ImplCvgZ
317
317
// CHECK: hop_to_executor [[RED:%[0-9]+]] : $RedActorImpl
318
+ // CHECK-NEXT: end_borrow [[RED]]
318
319
// CHECK-NEXT: begin_borrow
319
320
// CHECK-NEXT: apply
320
321
// CHECK: hop_to_executor [[GENERIC_EXEC:%[0-9]+]] : $Optional<Builtin.Executor>
@@ -464,10 +465,37 @@ func asyncWithUnsafeInheritance_hopback() async {
464
465
// CHECK-NEXT: [[ACTOR:%.*]] = apply [[ACTOR_GETTER]]([[METATYPE]])
465
466
// CHECK-NEXT: [[BORROWED_ACTOR:%.*]] = begin_borrow [[ACTOR]]
466
467
// CHECK-NEXT: hop_to_executor [[BORROWED_ACTOR]]
467
- // CHECK-NEXT: apply [[FN]]({{%.*}})
468
468
// CHECK-NEXT: end_borrow [[BORROWED_ACTOR]]
469
+ // CHECK-NEXT: apply [[FN]]({{%.*}})
469
470
// CHECK-NEXT: destroy_value [[ACTOR]]
470
471
// CHECK-NEXT: tuple
471
472
// CHECK-NEXT: return
472
473
await redFn ( 0 )
473
474
}
475
+
476
+ // Previously we would break Ownership SSA when passing a below since when we
477
+ // emitted the hop_to_executor, we would unnecessarily borrow a over the entire
478
+ // apply (we only needed it to call hop_to_executor). This would cause an OSSA
479
+ // violation since we are going to consume it as part of calling Klass's
480
+ // initializer.
481
+
482
+ // CHECK-LABEL: sil hidden [ossa] @$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF : $@convention(thin) @async () -> () {
483
+ // CHECK: hop_to_executor %0
484
+ // CHECK: [[ACTOR:%.*]] = init_existential_ref {{%.*}}
485
+ // CHECK: [[INIT_FN:%.*]] = function_ref @$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF5KlassL_C2onADScA_pYi_tcfC : $@convention(method) (@sil_isolated @owned any Actor, @thick Klass.Type) -> @owned Klass
486
+ // CHECK: [[BORROW:%.*]] = begin_borrow [[ACTOR]]
487
+ // CHECK: hop_to_executor [[BORROW]]
488
+ // CHECK: end_borrow [[BORROW]]
489
+ // CHECK: apply [[INIT_FN]]([[ACTOR]],
490
+ // CHECK: hop_to_executor %0
491
+ // CHECK: } // end sil function '$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF'
492
+ func validateHopToExecutorLifetimeShortEnough( ) async {
493
+ class Klass {
494
+ init (
495
+ on isolation: isolated Actor,
496
+ ) { }
497
+ }
498
+
499
+ let a = MyActor ( )
500
+ _ = await Klass ( on: a)
501
+ }
0 commit comments