@@ -1025,10 +1025,9 @@ void SILGenFunction::collectThunkParams(
1025
1025
auto functionArgument =
1026
1026
B.createInputFunctionArgument (inContextParamTy, loc);
1027
1027
1028
- // If we are told to not propagate the isolated parameter and this is the
1029
- // implicit leading/isolated parameter, continue.
1030
- if (options.contains (ThunkGenFlag::ConvertingToNonIsolatedCaller) &&
1031
- param.hasOption (SILParameterInfo::ImplicitLeading) &&
1028
+ // If our thunk has an implicit param and we are being asked to forward it,
1029
+ // to the callee, skip it. We are going to handle it especially later.
1030
+ if (param.hasOption (SILParameterInfo::ImplicitLeading) &&
1032
1031
param.hasOption (SILParameterInfo::Isolated))
1033
1032
continue ;
1034
1033
params.push_back (functionArgument);
@@ -2925,8 +2924,11 @@ forwardFunctionArguments(SILGenFunction &SGF, SILLocation loc,
2925
2924
SmallVectorImpl<SILValue> &forwardedArgs,
2926
2925
SILGenFunction::ThunkGenOptions options = {}) {
2927
2926
auto argTypes = fTy ->getParameters ();
2927
+
2928
+ // If our callee has an implicit parameter, we have already inserted it, so
2929
+ // drop it from argTypes.
2928
2930
if (options.contains (
2929
- SILGenFunction::ThunkGenFlag::ConvertingFromNonIsolatedCaller )) {
2931
+ SILGenFunction::ThunkGenFlag::CalleeHasImplicitIsolatedParam )) {
2930
2932
argTypes = argTypes.drop_front ();
2931
2933
}
2932
2934
@@ -5453,16 +5455,11 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5453
5455
// isolated parameter preventing us from having to memcpy over the array.
5454
5456
if (outputSubstType->isAsync ()) {
5455
5457
if (outputSubstType->getIsolation ().getKind () ==
5456
- FunctionTypeIsolation::Kind::NonIsolatedCaller &&
5457
- inputSubstType->getIsolation ().getKind () !=
5458
- FunctionTypeIsolation::Kind::NonIsolatedCaller)
5459
- options |= ThunkGenFlag::ConvertingToNonIsolatedCaller;
5460
-
5461
- if (outputSubstType->getIsolation ().getKind () !=
5462
- FunctionTypeIsolation::Kind::NonIsolatedCaller &&
5463
- inputSubstType->getIsolation ().getKind () ==
5464
- FunctionTypeIsolation::Kind::NonIsolatedCaller)
5465
- options |= ThunkGenFlag::ConvertingFromNonIsolatedCaller;
5458
+ FunctionTypeIsolation::Kind::NonIsolatedCaller)
5459
+ options |= ThunkGenFlag::ThunkHasImplicitIsolatedParam;
5460
+ if (inputSubstType->getIsolation ().getKind () ==
5461
+ FunctionTypeIsolation::Kind::NonIsolatedCaller)
5462
+ options |= ThunkGenFlag::CalleeHasImplicitIsolatedParam;
5466
5463
}
5467
5464
5468
5465
SmallVector<ManagedValue, 8 > params;
@@ -5485,14 +5482,16 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5485
5482
outputErasedIsolation = params.pop_back_val ();
5486
5483
}
5487
5484
5488
- if (!SGF. F . maybeGetIsolatedArgument () && argTypes.size () &&
5485
+ if (argTypes.size () &&
5489
5486
argTypes.front ().hasOption (SILParameterInfo::Isolated) &&
5490
5487
argTypes.front ().hasOption (SILParameterInfo::ImplicitLeading))
5491
- options |= ThunkGenFlag::ConvertingFromNonIsolatedCaller ;
5488
+ options |= ThunkGenFlag::CalleeHasImplicitIsolatedParam ;
5492
5489
5493
- // If we are converting to nonisolated caller, we are going to have an extra
5494
- // parameter in our argTypes that we need to drop.
5495
- if (options.contains (ThunkGenFlag::ConvertingFromNonIsolatedCaller))
5490
+ // If we are converting from a nonisolated caller, we are going to have an
5491
+ // extra parameter in our argTypes that we need to drop. We are going to
5492
+ // handle it separately later so that TranslateArguments does not have to know
5493
+ // anything about it.
5494
+ if (options.contains (ThunkGenFlag::CalleeHasImplicitIsolatedParam))
5496
5495
argTypes = argTypes.drop_front ();
5497
5496
5498
5497
// We may need to establish the right executor for the input function.
@@ -5597,7 +5596,7 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
5597
5596
5598
5597
// If we are thunking a nonisolated caller to nonisolated or global actor, we
5599
5598
// need to load the actor.
5600
- if (options.contains (ThunkGenFlag::ConvertingFromNonIsolatedCaller )) {
5599
+ if (options.contains (ThunkGenFlag::CalleeHasImplicitIsolatedParam )) {
5601
5600
auto outputIsolation = outputSubstType->getIsolation ();
5602
5601
switch (outputIsolation.getKind ()) {
5603
5602
case FunctionTypeIsolation::Kind::NonIsolated:
@@ -7264,11 +7263,60 @@ void SILGenFunction::emitProtocolWitness(
7264
7263
FullExpr scope (Cleanups, cleanupLoc);
7265
7264
FormalEvaluationScope formalEvalScope (*this );
7266
7265
7266
+ // Grab the type of our thunk.
7267
7267
auto thunkTy = F.getLoweredFunctionType ();
7268
7268
7269
+ // Then get the type of the witness.
7270
+ auto witnessKind = getWitnessDispatchKind (witness, isSelfConformance);
7271
+ auto witnessInfo = getConstantInfo (getTypeExpansionContext (), witness);
7272
+ CanAnyFunctionType witnessSubstTy = witnessInfo.LoweredType ;
7273
+ if (auto genericFnType = dyn_cast<GenericFunctionType>(witnessSubstTy)) {
7274
+ witnessSubstTy = cast<FunctionType>(
7275
+ genericFnType->substGenericArgs (witnessSubs)->getCanonicalType ());
7276
+ }
7277
+
7278
+ assert (!witnessSubstTy->hasError ());
7279
+
7280
+ if (auto genericFnType = dyn_cast<GenericFunctionType>(reqtSubstTy)) {
7281
+ auto forwardingSubs = F.getForwardingSubstitutionMap ();
7282
+ reqtSubstTy = cast<FunctionType>(
7283
+ genericFnType->substGenericArgs (forwardingSubs)->getCanonicalType ());
7284
+ } else {
7285
+ reqtSubstTy = cast<FunctionType>(
7286
+ F.mapTypeIntoContext (reqtSubstTy)->getCanonicalType ());
7287
+ }
7288
+
7289
+ assert (!reqtSubstTy->hasError ());
7290
+
7291
+ // Get the lowered type of the witness.
7292
+ auto origWitnessFTy = getWitnessFunctionType (getTypeExpansionContext (), SGM,
7293
+ witness, witnessKind);
7294
+ auto witnessFTy = origWitnessFTy;
7295
+ if (!witnessSubs.empty ()) {
7296
+ witnessFTy = origWitnessFTy->substGenericArgs (SGM.M , witnessSubs,
7297
+ getTypeExpansionContext ());
7298
+ }
7299
+
7300
+ // Now that we have the type information in hand, we can generate the thunk
7301
+ // body.
7302
+
7303
+ using ThunkGenFlag = SILGenFunction::ThunkGenFlag;
7304
+ auto options = SILGenFunction::ThunkGenOptions ();
7305
+
7306
+ {
7307
+ auto thunkIsolatedParam = thunkTy->maybeGetIsolatedParameter ();
7308
+ if (thunkIsolatedParam &&
7309
+ thunkIsolatedParam->hasOption (SILParameterInfo::ImplicitLeading))
7310
+ options |= ThunkGenFlag::ThunkHasImplicitIsolatedParam;
7311
+ auto witnessIsolatedParam = witnessFTy->maybeGetIsolatedParameter ();
7312
+ if (witnessIsolatedParam &&
7313
+ witnessIsolatedParam->hasOption (SILParameterInfo::ImplicitLeading))
7314
+ options |= ThunkGenFlag::CalleeHasImplicitIsolatedParam;
7315
+ }
7316
+
7269
7317
SmallVector<ManagedValue, 8 > origParams;
7270
7318
SmallVector<ManagedValue, 8 > thunkIndirectResults;
7271
- collectThunkParams (loc, origParams, &thunkIndirectResults);
7319
+ collectThunkParams (loc, origParams, &thunkIndirectResults, nullptr , options );
7272
7320
7273
7321
if (witness.getDecl ()->requiresUnavailableDeclABICompatibilityStubs ())
7274
7322
emitApplyOfUnavailableCodeReached ();
@@ -7305,40 +7353,7 @@ void SILGenFunction::emitProtocolWitness(
7305
7353
}
7306
7354
}
7307
7355
7308
- // Get the type of the witness.
7309
- auto witnessKind = getWitnessDispatchKind (witness, isSelfConformance);
7310
- auto witnessInfo = getConstantInfo (getTypeExpansionContext (), witness);
7311
- CanAnyFunctionType witnessSubstTy = witnessInfo.LoweredType ;
7312
- if (auto genericFnType = dyn_cast<GenericFunctionType>(witnessSubstTy)) {
7313
- witnessSubstTy = cast<FunctionType>(genericFnType
7314
- ->substGenericArgs (witnessSubs)
7315
- ->getCanonicalType ());
7316
- }
7317
-
7318
- assert (!witnessSubstTy->hasError ());
7319
-
7320
- if (auto genericFnType = dyn_cast<GenericFunctionType>(reqtSubstTy)) {
7321
- auto forwardingSubs = F.getForwardingSubstitutionMap ();
7322
- reqtSubstTy = cast<FunctionType>(genericFnType
7323
- ->substGenericArgs (forwardingSubs)
7324
- ->getCanonicalType ());
7325
- } else {
7326
- reqtSubstTy = cast<FunctionType>(F.mapTypeIntoContext (reqtSubstTy)
7327
- ->getCanonicalType ());
7328
- }
7329
-
7330
- assert (!reqtSubstTy->hasError ());
7331
-
7332
- // Get the lowered type of the witness.
7333
- auto origWitnessFTy = getWitnessFunctionType (getTypeExpansionContext (), SGM,
7334
- witness, witnessKind);
7335
- auto witnessFTy = origWitnessFTy;
7336
- if (!witnessSubs.empty ()) {
7337
- witnessFTy = origWitnessFTy->substGenericArgs (SGM.M , witnessSubs,
7338
- getTypeExpansionContext ());
7339
- }
7340
7356
auto witnessUnsubstTy = witnessFTy->getUnsubstitutedType (SGM.M );
7341
-
7342
7357
auto reqtSubstParams = reqtSubstTy.getParams ();
7343
7358
auto witnessSubstParams = witnessSubstTy.getParams ();
7344
7359
@@ -7360,8 +7375,8 @@ void SILGenFunction::emitProtocolWitness(
7360
7375
// @convention(c) () -> ()
7361
7376
// . We do this by simply omitting the last params.
7362
7377
// TODO: fix this for static C++ methods.
7363
- if (witness. getDecl ()-> getClangDecl () &&
7364
- isa<clang::CXXConstructorDecl>( witness.getDecl ()->getClangDecl ())) {
7378
+ if (isa_and_nonnull<clang::CXXConstructorDecl>(
7379
+ witness.getDecl ()->getClangDecl ())) {
7365
7380
origParams.pop_back ();
7366
7381
reqtSubstParams = reqtSubstParams.drop_back ();
7367
7382
ignoreFinalInputOrigParam = true ;
@@ -7379,15 +7394,19 @@ void SILGenFunction::emitProtocolWitness(
7379
7394
// Translate the argument values from the requirement abstraction level to
7380
7395
// the substituted signature of the witness.
7381
7396
SmallVector<ManagedValue, 8 > witnessParams;
7397
+ auto witnessParamInfos = witnessUnsubstTy->getParameters ();
7398
+
7399
+ // If we are transforming to a callee with an implicit param, drop the
7400
+ // implicit param so that we can insert it again later. This ensures
7401
+ // TranslateArguments does not need to know about this.
7402
+ if (options.contains (ThunkGenFlag::CalleeHasImplicitIsolatedParam))
7403
+ witnessParamInfos = witnessParamInfos.drop_front ();
7404
+
7382
7405
AbstractionPattern witnessOrigTy (witnessInfo.LoweredType );
7383
- TranslateArguments (*this , loc,
7384
- origParams, witnessParams,
7385
- witnessUnsubstTy, witnessUnsubstTy->getParameters ())
7386
- .process (witnessOrigTy,
7387
- witnessSubstParams,
7388
- reqtOrigTy,
7389
- reqtSubstParams,
7390
- ignoreFinalInputOrigParam);
7406
+ TranslateArguments (*this , loc, origParams, witnessParams, witnessUnsubstTy,
7407
+ witnessParamInfos)
7408
+ .process (witnessOrigTy, witnessSubstParams, reqtOrigTy, reqtSubstParams,
7409
+ ignoreFinalInputOrigParam);
7391
7410
7392
7411
SILValue witnessFnRef = getWitnessFunctionRef (*this , witness,
7393
7412
origWitnessFTy,
@@ -7420,8 +7439,61 @@ void SILGenFunction::emitProtocolWitness(
7420
7439
}
7421
7440
}
7422
7441
7442
+ // Now that we have translated arguments and inserted our thunk indirect
7443
+ // parameters... before we forward those arguments, insert the implicit
7444
+ // leading parameter.
7445
+ if (options.contains (ThunkGenFlag::CalleeHasImplicitIsolatedParam)) {
7446
+ auto reqtIsolation =
7447
+ swift::getActorIsolation (requirement.getAbstractFunctionDecl ());
7448
+ switch (reqtIsolation) {
7449
+ case ActorIsolation::Unspecified:
7450
+ case ActorIsolation::Nonisolated:
7451
+ case ActorIsolation::NonisolatedUnsafe:
7452
+ args.push_back (emitNonIsolatedIsolation (loc).getValue ());
7453
+ break ;
7454
+ case ActorIsolation::Erased:
7455
+ llvm::report_fatal_error (" Found erased actor isolation?!" );
7456
+ break ;
7457
+ case ActorIsolation::GlobalActor: {
7458
+ auto globalActor = reqtIsolation.getGlobalActor ()->getCanonicalType ();
7459
+ args.push_back (emitGlobalActorIsolation (loc, globalActor).getValue ());
7460
+ break ;
7461
+ }
7462
+ case ActorIsolation::ActorInstance:
7463
+ case ActorIsolation::CallerIsolationInheriting: {
7464
+ auto witnessIsolation =
7465
+ swift::getActorIsolation (witness.getAbstractFunctionDecl ());
7466
+ switch (witnessIsolation) {
7467
+ case ActorIsolation::Unspecified:
7468
+ case ActorIsolation::Nonisolated:
7469
+ case ActorIsolation::NonisolatedUnsafe:
7470
+ args.push_back (emitNonIsolatedIsolation (loc).getValue ());
7471
+ break ;
7472
+ case ActorIsolation::Erased:
7473
+ llvm::report_fatal_error (" Found erased actor isolation?!" );
7474
+ break ;
7475
+ case ActorIsolation::GlobalActor: {
7476
+ auto globalActor =
7477
+ witnessIsolation.getGlobalActor ()->getCanonicalType ();
7478
+ args.push_back (emitGlobalActorIsolation (loc, globalActor).getValue ());
7479
+ break ;
7480
+ }
7481
+ case ActorIsolation::ActorInstance:
7482
+ case ActorIsolation::CallerIsolationInheriting: {
7483
+ auto isolatedArg = F.maybeGetIsolatedArgument ();
7484
+ assert (isolatedArg);
7485
+ args.push_back (isolatedArg);
7486
+ break ;
7487
+ }
7488
+ }
7489
+ break ;
7490
+ }
7491
+ }
7492
+ }
7493
+
7423
7494
// - the rest of the arguments
7424
- forwardFunctionArguments (*this , loc, witnessFTy, witnessParams, args);
7495
+ forwardFunctionArguments (*this , loc, witnessFTy, witnessParams, args,
7496
+ options);
7425
7497
7426
7498
// Perform the call.
7427
7499
SILType witnessSILTy = SILType::getPrimitiveObjectType (witnessFTy);
0 commit comments