@@ -1025,10 +1025,9 @@ void SILGenFunction::collectThunkParams(
10251025 auto functionArgument =
10261026 B.createInputFunctionArgument (inContextParamTy, loc);
10271027
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) &&
10321031 param.hasOption (SILParameterInfo::Isolated))
10331032 continue ;
10341033 params.push_back (functionArgument);
@@ -2925,8 +2924,11 @@ forwardFunctionArguments(SILGenFunction &SGF, SILLocation loc,
29252924 SmallVectorImpl<SILValue> &forwardedArgs,
29262925 SILGenFunction::ThunkGenOptions options = {}) {
29272926 auto argTypes = fTy ->getParameters ();
2927+
2928+ // If our callee has an implicit parameter, we have already inserted it, so
2929+ // drop it from argTypes.
29282930 if (options.contains (
2929- SILGenFunction::ThunkGenFlag::ConvertingFromNonIsolatedCaller )) {
2931+ SILGenFunction::ThunkGenFlag::CalleeHasImplicitIsolatedParam )) {
29302932 argTypes = argTypes.drop_front ();
29312933 }
29322934
@@ -5453,16 +5455,11 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
54535455 // isolated parameter preventing us from having to memcpy over the array.
54545456 if (outputSubstType->isAsync ()) {
54555457 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;
54665463 }
54675464
54685465 SmallVector<ManagedValue, 8 > params;
@@ -5485,14 +5482,16 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
54855482 outputErasedIsolation = params.pop_back_val ();
54865483 }
54875484
5488- if (!SGF. F . maybeGetIsolatedArgument () && argTypes.size () &&
5485+ if (argTypes.size () &&
54895486 argTypes.front ().hasOption (SILParameterInfo::Isolated) &&
54905487 argTypes.front ().hasOption (SILParameterInfo::ImplicitLeading))
5491- options |= ThunkGenFlag::ConvertingFromNonIsolatedCaller ;
5488+ options |= ThunkGenFlag::CalleeHasImplicitIsolatedParam ;
54925489
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))
54965495 argTypes = argTypes.drop_front ();
54975496
54985497 // We may need to establish the right executor for the input function.
@@ -5597,7 +5596,7 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
55975596
55985597 // If we are thunking a nonisolated caller to nonisolated or global actor, we
55995598 // need to load the actor.
5600- if (options.contains (ThunkGenFlag::ConvertingFromNonIsolatedCaller )) {
5599+ if (options.contains (ThunkGenFlag::CalleeHasImplicitIsolatedParam )) {
56015600 auto outputIsolation = outputSubstType->getIsolation ();
56025601 switch (outputIsolation.getKind ()) {
56035602 case FunctionTypeIsolation::Kind::NonIsolated:
@@ -7264,11 +7263,60 @@ void SILGenFunction::emitProtocolWitness(
72647263 FullExpr scope (Cleanups, cleanupLoc);
72657264 FormalEvaluationScope formalEvalScope (*this );
72667265
7266+ // Grab the type of our thunk.
72677267 auto thunkTy = F.getLoweredFunctionType ();
72687268
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+
72697317 SmallVector<ManagedValue, 8 > origParams;
72707318 SmallVector<ManagedValue, 8 > thunkIndirectResults;
7271- collectThunkParams (loc, origParams, &thunkIndirectResults);
7319+ collectThunkParams (loc, origParams, &thunkIndirectResults, nullptr , options );
72727320
72737321 if (witness.getDecl ()->requiresUnavailableDeclABICompatibilityStubs ())
72747322 emitApplyOfUnavailableCodeReached ();
@@ -7305,40 +7353,7 @@ void SILGenFunction::emitProtocolWitness(
73057353 }
73067354 }
73077355
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- }
73407356 auto witnessUnsubstTy = witnessFTy->getUnsubstitutedType (SGM.M );
7341-
73427357 auto reqtSubstParams = reqtSubstTy.getParams ();
73437358 auto witnessSubstParams = witnessSubstTy.getParams ();
73447359
@@ -7360,8 +7375,8 @@ void SILGenFunction::emitProtocolWitness(
73607375 // @convention(c) () -> ()
73617376 // . We do this by simply omitting the last params.
73627377 // 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 ())) {
73657380 origParams.pop_back ();
73667381 reqtSubstParams = reqtSubstParams.drop_back ();
73677382 ignoreFinalInputOrigParam = true ;
@@ -7379,15 +7394,19 @@ void SILGenFunction::emitProtocolWitness(
73797394 // Translate the argument values from the requirement abstraction level to
73807395 // the substituted signature of the witness.
73817396 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+
73827405 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);
73917410
73927411 SILValue witnessFnRef = getWitnessFunctionRef (*this , witness,
73937412 origWitnessFTy,
@@ -7420,8 +7439,61 @@ void SILGenFunction::emitProtocolWitness(
74207439 }
74217440 }
74227441
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+
74237494 // - the rest of the arguments
7424- forwardFunctionArguments (*this , loc, witnessFTy, witnessParams, args);
7495+ forwardFunctionArguments (*this , loc, witnessFTy, witnessParams, args,
7496+ options);
74257497
74267498 // Perform the call.
74277499 SILType witnessSILTy = SILType::getPrimitiveObjectType (witnessFTy);
0 commit comments