@@ -17,6 +17,16 @@ public enum FakeOptional<T> {
1717 case some(T)
1818}
1919
20+ sil @swift_asyncLet_finish : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
21+ sil @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
22+
23+ protocol Error {}
24+
25+ enum Optional<Wrapped> {
26+ case none
27+ case some(Wrapped)
28+ }
29+
2030// CHECK-LABEL: begin running test 1 of 1 on eagerConsumneOwnedArg: ossa-lifetime-completion with: @argument
2131// CHECK-LABEL: OSSA lifetime completion: %0 = argument of bb0 : $C
2232// CHECK: sil [ossa] @eagerConsumneOwnedArg : $@convention(thin) (@owned C) -> () {
@@ -461,3 +471,30 @@ right:
461471 end_borrow %c : $C
462472 unreachable
463473}
474+
475+ // Nothing to check here--the output is the same as the input. Verify that
476+ // completing the lifetime of a value used by a startAsyncLetWithLocalBuffer
477+ // doesn't crash when visiting an endAsyncLetLifetime.
478+ sil [ossa] @async_let : $@convention(thin) @async () -> () {
479+ bb0:
480+ %result_addr = alloc_stack $()
481+ %result_ptr = address_to_pointer %result_addr : $*() to $Builtin.RawPointer
482+ %task_options = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
483+ %callee_pa = partial_apply [callee_guaranteed] undef() : $@convention(thin) @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
484+ %callee_noescape = convert_escape_to_noescape [not_guaranteed] %callee_pa : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
485+ to $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
486+ specify_test "ossa-lifetime-completion %callee_noescape"
487+ %async_let = builtin "startAsyncLetWithLocalBuffer"<()>(
488+ %task_options : $Optional<Builtin.RawPointer>,
489+ %callee_noescape : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>,
490+ %result_ptr : $Builtin.RawPointer
491+ ) : $Builtin.RawPointer
492+ %get = function_ref @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
493+ apply %get(%async_let, %result_ptr) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
494+ builtin "endAsyncLetLifetime"(%async_let : $Builtin.RawPointer) : $()
495+ destroy_value %callee_noescape : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
496+ destroy_value %callee_pa : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
497+ %retval = load [trivial] %result_addr : $*()
498+ dealloc_stack %result_addr : $*()
499+ return %retval : $()
500+ }
0 commit comments