@@ -270,9 +270,9 @@ struct BlueActor {
270270// CHECK: [[R:%[0-9]+]] = apply [[GETTER]]([[REDMT]]) : $@convention(method) (@thin RedActor.Type) -> @owned RedActorImpl
271271// CHECK: [[REDEXE:%[0-9]+]] = begin_borrow [[R]] : $RedActorImpl
272272// CHECK: hop_to_executor [[REDEXE]] : $RedActorImpl
273+ // CHECK-NEXT: end_borrow [[REDEXE]]
273274 // ---- now invoke redFn, hop back to Blue, and clean-up ----
274275// CHECK-NEXT: {{%[0-9]+}} = apply [[CALLEE]]([[ARG]]) : $@convention(thin) (Int) -> ()
275- // CHECK-NEXT: end_borrow [[REDEXE]] : $RedActorImpl
276276// CHECK-NEXT: destroy_value [[R]] : $RedActorImpl
277277// CHECK-NEXT: hop_to_executor [[BLUEEXE]] : $BlueActorImpl
278278// CHECK: end_borrow [[BLUEEXE]] : $BlueActorImpl
@@ -287,8 +287,8 @@ struct BlueActor {
287287// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] :
288288// CHECK: [[BORROW:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $RedActorImpl
289289// CHECK-NEXT: hop_to_executor [[BORROW]] : $RedActorImpl
290- // CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
291290// CHECK-NEXT: end_borrow [[BORROW]] : $RedActorImpl
291+ // CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
292292// CHECK-NEXT: destroy_value
293293// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]]
294294// CHECK: } // end sil function '$s4test20unspecifiedAsyncFuncyyYaF'
@@ -315,6 +315,7 @@ func anotherUnspecifiedAsyncFunc(_ red : RedActorImpl) async {
315315// CHECK: hop_to_executor [[GENERIC_EXEC]] :
316316// CHECK: function_ref @$s4test8RedActorV6sharedAA0bC4ImplCvgZ
317317// CHECK: hop_to_executor [[RED:%[0-9]+]] : $RedActorImpl
318+ // CHECK-NEXT: end_borrow [[RED]]
318319// CHECK-NEXT: begin_borrow
319320// CHECK-NEXT: apply
320321// CHECK: hop_to_executor [[GENERIC_EXEC:%[0-9]+]] : $Optional<Builtin.Executor>
@@ -464,10 +465,37 @@ func asyncWithUnsafeInheritance_hopback() async {
464465 // CHECK-NEXT: [[ACTOR:%.*]] = apply [[ACTOR_GETTER]]([[METATYPE]])
465466 // CHECK-NEXT: [[BORROWED_ACTOR:%.*]] = begin_borrow [[ACTOR]]
466467 // CHECK-NEXT: hop_to_executor [[BORROWED_ACTOR]]
467- // CHECK-NEXT: apply [[FN]]({{%.*}})
468468 // CHECK-NEXT: end_borrow [[BORROWED_ACTOR]]
469+ // CHECK-NEXT: apply [[FN]]({{%.*}})
469470 // CHECK-NEXT: destroy_value [[ACTOR]]
470471 // CHECK-NEXT: tuple
471472 // CHECK-NEXT: return
472473 await redFn ( 0 )
473474}
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