@@ -511,18 +511,33 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
511
511
// Get the block invocation function for the given completion block type.
512
512
auto completionHandlerIndex = calleeTypeInfo.foreign .async
513
513
->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
+ }
517
526
SILFunction *impl = SGF.SGM
518
- .getOrCreateForeignAsyncCompletionHandlerImplFunction (implTy ,
527
+ .getOrCreateForeignAsyncCompletionHandlerImplFunction (impFnTy ,
519
528
continuationTy,
520
529
*calleeTypeInfo.foreign .async );
521
- auto implRef = SGF.B .createFunctionRef (loc, impl);
530
+ auto impRef = SGF.B .createFunctionRef (loc, impl);
522
531
523
532
// 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
+
526
541
// We don't need to manage the block because it's still on the stack. We
527
542
// know we won't escape it locally so the callee can be responsible for
528
543
// _Block_copy-ing it.
0 commit comments