@@ -1593,13 +1593,17 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
15931593 }
15941594 }
15951595
1596- // If we are bridging a Swift method with an Any return value, create a
1597- // stack allocation to hold the result, since Any is address-only.
1596+ // If we are bridging a Swift method with Any return value(s) , create a
1597+ // stack allocation to hold the result(s) , since Any is address-only.
15981598 SmallVector<SILValue, 4 > args;
1599-
16001599 if (substConv.hasIndirectSILResults ()) {
1601- args.push_back (emitTemporaryAllocation (
1602- loc, substConv.getSingleSILResultType (getTypeExpansionContext ())));
1600+ for (auto result : substConv.getResults ()) {
1601+ if (!substConv.isSILIndirect (result)) {
1602+ continue ;
1603+ }
1604+ args.push_back (emitTemporaryAllocation (
1605+ loc, substConv.getSILType (result, getTypeExpansionContext ())));
1606+ }
16031607 }
16041608
16051609 // If the '@objc' was inferred due to deprecated rules,
@@ -1792,14 +1796,29 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
17921796 pushErrorFlag (/* has error*/ false , completionHandlerArgs);
17931797 continue ;
17941798 }
1795- pushArg (asyncResult,
1796- nativeFormalResultType,
1797- completionTy->getParameters ()[i]);
1799+
1800+ // Use the indirect return argument if the result is indirect.
1801+ if (substConv.hasIndirectSILResults ()) {
1802+ pushArg (emitManagedRValueWithCleanup (args[0 ]),
1803+ nativeFormalResultType,
1804+ completionTy->getParameters ()[i]);
1805+ } else {
1806+ pushArg (asyncResult,
1807+ nativeFormalResultType,
1808+ completionTy->getParameters ()[i]);
1809+ }
17981810 }
17991811 } else {
18001812 // A tuple return maps to multiple completion handler parameters.
18011813 auto formalTuple = cast<TupleType>(nativeFormalResultType);
18021814
1815+ unsigned indirectResultI = 0 ;
1816+ unsigned directResultI = 0 ;
1817+
1818+ auto directResults = substConv.getDirectSILResults ();
1819+ auto hasMultipleDirectResults
1820+ = std::next (directResults.begin ()) != directResults.end ();
1821+
18031822 for (unsigned paramI : indices (completionTy->getParameters ())) {
18041823 if (errorParamIndex && paramI == *errorParamIndex) {
18051824 pushErrorPlaceholder ();
@@ -1813,7 +1832,21 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
18131832 - (errorFlagIndex && paramI > *errorFlagIndex);
18141833 auto param = completionTy->getParameters ()[paramI];
18151834 auto formalTy = formalTuple.getElementType (elementI);
1816- auto argPiece = B.createTupleExtract (loc, asyncResult, elementI);
1835+ ManagedValue argPiece;
1836+
1837+ auto result = substConv.getResults ()[elementI];
1838+ if (substConv.isSILIndirect (result)) {
1839+ // Take the arg piece from the indirect return arguments.
1840+ argPiece = emitManagedRValueWithCleanup (args[indirectResultI++]);
1841+ } else if (hasMultipleDirectResults) {
1842+ // Take the arg piece from one of the tuple elements of the direct
1843+ // result tuple from the apply.
1844+ argPiece = B.createTupleExtract (loc, asyncResult, directResultI++);
1845+ } else {
1846+ // Take the entire direct result from the apply as the arg piece.
1847+ argPiece = asyncResult;
1848+ }
1849+
18171850 pushArg (argPiece, formalTy, param);
18181851 }
18191852 }
@@ -1829,16 +1862,11 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
18291862 // The immediate function result is an empty tuple.
18301863 return SILUndef::get (SGM.Types .getEmptyTupleType (), F);
18311864 };
1832-
1865+
18331866 if (!substTy->hasErrorResult ()) {
18341867 // Create the apply.
18351868 result = B.createApply (loc, nativeFn, subs, args);
1836-
1837- if (substConv.hasIndirectSILResults ()) {
1838- assert (substTy->getNumResults () == 1 );
1839- result = args[0 ];
1840- }
1841-
1869+
18421870 // Leave the argument cleanup scope immediately. This isn't really
18431871 // necessary; it just limits lifetimes a little bit more.
18441872 argScope.pop ();
@@ -1849,6 +1877,10 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
18491877 if (foreignAsync) {
18501878 result = passResultToCompletionHandler (result);
18511879 } else {
1880+ if (substConv.hasIndirectSILResults ()) {
1881+ assert (substTy->getNumResults () == 1 );
1882+ result = args[0 ];
1883+ }
18521884 result = emitBridgeReturnValue (*this , loc, result, nativeFormalResultType,
18531885 bridgedFormalResultType, objcResultTy);
18541886 }
@@ -1864,17 +1896,16 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
18641896 SILValue nativeResult =
18651897 normalBB->createPhiArgument (swiftResultTy, OwnershipKind::Owned);
18661898
1867- if (substConv.hasIndirectSILResults ()) {
1868- assert (substTy->getNumResults () == 1 );
1869- nativeResult = args[0 ];
1870- }
1871-
18721899 if (foreignAsync) {
18731900 // If the function is async, pass the results as the success argument(s)
18741901 // to the completion handler, with a nil error.
18751902 passResultToCompletionHandler (nativeResult);
18761903 B.createBranch (loc, contBB);
18771904 } else {
1905+ if (substConv.hasIndirectSILResults ()) {
1906+ assert (substTy->getNumResults () == 1 );
1907+ nativeResult = args[0 ];
1908+ }
18781909 // In this branch, the eventual return value is mostly created
18791910 // by bridging the native return value, but we may need to
18801911 // adjust it slightly.
0 commit comments