Skip to content

Commit bd2a6a4

Browse files
committed
SILGen: Handle _Nullable completion handler arguments to imported async APIs.
1 parent f4e74f7 commit bd2a6a4

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

lib/SILGen/ResultPlan.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -511,18 +511,33 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
511511
// Get the block invocation function for the given completion block type.
512512
auto completionHandlerIndex = calleeTypeInfo.foreign.async
513513
->completionHandlerParamIndex();
514-
auto implTy = cast<SILFunctionType>(calleeTypeInfo.substFnType
515-
->getParameters()[completionHandlerIndex]
516-
.getInterfaceType());
514+
auto impTy = SGF.getSILType(calleeTypeInfo.substFnType
515+
->getParameters()[completionHandlerIndex],
516+
calleeTypeInfo.substFnType);
517+
bool handlerIsOptional;
518+
CanSILFunctionType impFnTy;
519+
if (auto impObjTy = impTy.getOptionalObjectType()) {
520+
handlerIsOptional = true;
521+
impFnTy = cast<SILFunctionType>(impObjTy.getASTType());
522+
} else {
523+
handlerIsOptional = false;
524+
impFnTy = cast<SILFunctionType>(impTy.getASTType());
525+
}
517526
SILFunction *impl = SGF.SGM
518-
.getOrCreateForeignAsyncCompletionHandlerImplFunction(implTy,
527+
.getOrCreateForeignAsyncCompletionHandlerImplFunction(impFnTy,
519528
continuationTy,
520529
*calleeTypeInfo.foreign.async);
521-
auto implRef = SGF.B.createFunctionRef(loc, impl);
530+
auto impRef = SGF.B.createFunctionRef(loc, impl);
522531

523532
// Initialize the block object for the completion handler.
524-
auto block = SGF.B.createInitBlockStorageHeader(loc, blockStorage, implRef,
525-
SILType::getPrimitiveObjectType(implTy), {});
533+
SILValue block = SGF.B.createInitBlockStorageHeader(loc, blockStorage,
534+
impRef, SILType::getPrimitiveObjectType(impFnTy), {});
535+
536+
// Wrap it in optional if the callee expects if.
537+
if (handlerIsOptional) {
538+
block = SGF.B.createOptionalSome(loc, block, impTy);
539+
}
540+
526541
// We don't need to manage the block because it's still on the stack. We
527542
// know we won't escape it locally so the callee can be responsible for
528543
// _Block_copy-ing it.

test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ typedef void (^CompletionHandler)(NSString * _Nullable, NSString * _Nullable_res
4444

4545
-(void)repeatTrick:(NSString *)trick completionHandler:(void (^)(NSInteger))handler __attribute__((swift_async(none)));
4646

47+
-(void)doSomethingSlowNullably:(NSString *)operation completionHandler:(void (^ _Nullable)(NSInteger))handler;
4748
@end
4849

4950
@protocol RefrigeratorDelegate<NSObject>

test/SILGen/objc_async.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ func testSlowServer(slowServer: SlowServer) async throws {
2222
// CHECK: dealloc_stack [[RESUME_BUF]]
2323
let _: Int = await slowServer.doSomethingSlow("mail")
2424

25+
let _: Int = await slowServer.doSomethingSlowNullably("mail")
26+
2527
// CHECK: [[RESUME_BUF:%.*]] = alloc_stack $String
2628
// CHECK: [[METHOD:%.*]] = objc_method {{.*}} $@convention(objc_method) (@convention(block) (Optional<NSString>, Optional<NSError>) -> (), SlowServer) -> ()
2729
// CHECK: [[CONT:%.*]] = get_async_continuation_addr [throws] String, [[RESUME_BUF]]

0 commit comments

Comments
 (0)