@@ -261,19 +261,23 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
261261 auto continuationVal = SGF.B .createLoad (loc, continuationAddr,
262262 LoadOwnershipQualifier::Trivial);
263263 auto continuation = ManagedValue::forUnmanaged (continuationVal);
264-
264+
265265 // Check for an error if the convention includes one.
266- auto errorIndex = convention.completionHandlerErrorParamIndex ();
267- auto flagIndex = convention.completionHandlerFlagParamIndex ();
266+ // Increment the error and flag indices if present. They do not account
267+ // for the fact that they are preceded by the block_storage arguments.
268+ auto errorIndex = convention.completionHandlerErrorParamIndex ().map (
269+ [](auto original) { return original + 1 ; });
270+ auto flagIndex = convention.completionHandlerFlagParamIndex ().map (
271+ [](auto original) { return original + 1 ; });
268272
269273 FuncDecl *resumeIntrinsic;
270274
271275 SILBasicBlock *returnBB = nullptr ;
272276 if (errorIndex) {
273277 resumeIntrinsic = getResumeUnsafeThrowingContinuation ();
274278 auto errorIntrinsic = getResumeUnsafeThrowingContinuationWithError ();
275-
276- auto errorArgument = params[*errorIndex + 1 ];
279+
280+ auto errorArgument = params[*errorIndex];
277281 auto someErrorBB = SGF.createBasicBlock (FunctionSection::Postmatter);
278282 auto noneErrorBB = SGF.createBasicBlock ();
279283 returnBB = SGF.createBasicBlockAfter (noneErrorBB);
@@ -282,8 +286,8 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
282286 // Check whether there's an error, based on the presence of a flag
283287 // parameter. If there is a flag parameter, test it against zero.
284288 if (flagIndex) {
285- auto flagArgument = params[*flagIndex + 1 ];
286-
289+ auto flagArgument = params[*flagIndex];
290+
287291 // The flag must be an integer type. Get the underlying builtin
288292 // integer field from it.
289293 auto builtinFlagArg = SGF.emitUnwrapIntegerResult (loc, flagArgument.getValue ());
@@ -378,31 +382,31 @@ SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
378382 bridgedArg.forwardInto (SGF, loc, destBuf);
379383 };
380384
385+ // Collect the indices which correspond to the values to be returned.
386+ SmallVector<unsigned long , 4 > paramIndices;
387+ for (auto index : indices (params)) {
388+ // The first index is the block_storage parameter.
389+ if (index == 0 )
390+ continue ;
391+ if (errorIndex && index == *errorIndex)
392+ continue ;
393+ if (flagIndex && index == *flagIndex)
394+ continue ;
395+ paramIndices.push_back (index);
396+ }
381397 if (auto resumeTuple = dyn_cast<TupleType>(resumeType)) {
398+ assert (paramIndices.size () == resumeTuple->getNumElements ());
382399 assert (params.size () == resumeTuple->getNumElements ()
383400 + 1 + (bool )errorIndex + (bool )flagIndex);
384401 for (unsigned i : indices (resumeTuple.getElementTypes ())) {
385- unsigned paramI = i;
386- if (errorIndex && paramI >= *errorIndex) {
387- ++paramI;
388- }
389- if (flagIndex && paramI >= *flagIndex) {
390- ++paramI;
391- }
392402 auto resumeEltBuf = SGF.B .createTupleElementAddr (loc,
393403 resumeArgBuf, i);
394- prepareArgument (resumeEltBuf, params[paramI + 1 ]);
404+ prepareArgument (resumeEltBuf, params[paramIndices[i] ]);
395405 }
396406 } else {
407+ assert (paramIndices.size () == 1 );
397408 assert (params.size () == 2 + (bool )errorIndex + (bool )flagIndex);
398- unsigned paramI = 0 ;
399- if (errorIndex && paramI >= *errorIndex) {
400- ++paramI;
401- }
402- if (flagIndex && paramI >= *flagIndex) {
403- ++paramI;
404- }
405- prepareArgument (resumeArgBuf, params[paramI + 1 ]);
409+ prepareArgument (resumeArgBuf, params[paramIndices[0 ]]);
406410 }
407411
408412 // Resume the continuation with the composed bridged result.
0 commit comments