@@ -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.
0 commit comments