@@ -3166,7 +3166,7 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
31663166 if (fn->getLoweredFunctionType ()->isPseudogeneric ())
31673167 extInfoBuilder = extInfoBuilder.withIsPseudogeneric ();
31683168
3169- // Add the function type as the parameter .
3169+ // Add the formal parameters of the expected type to the thunk .
31703170 auto contextConvention =
31713171 fn->getTypeLowering (sourceType).isTrivial ()
31723172 ? ParameterConvention::Direct_Unowned
@@ -3175,6 +3175,17 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
31753175 params.append (expectedType->getParameters ().begin (),
31763176 expectedType->getParameters ().end ());
31773177
3178+ // Thunk functions can never be @isolated(any); we have to erase to that
3179+ // by partial application. Remove the attribute and add the capture
3180+ // parameter. This must always be the first capture.
3181+ if (extInfoBuilder.hasErasedIsolation ()) {
3182+ extInfoBuilder = extInfoBuilder.withErasedIsolation (false );
3183+ auto paramTy = SILType::getOpaqueIsolationType (fn->getASTContext ());
3184+ params.push_back ({paramTy.getASTType (),
3185+ ParameterConvention::Direct_Guaranteed});
3186+ }
3187+
3188+ // The next capture is the source function.
31783189 if (!differentiationThunkKind ||
31793190 *differentiationThunkKind == DifferentiationThunkKind::Reabstraction) {
31803191 params.push_back ({sourceType,
@@ -4839,6 +4850,10 @@ using ABICompatibilityCheckResult =
48394850ABICompatibilityCheckResult
48404851SILFunctionType::isABICompatibleWith (CanSILFunctionType other,
48414852 SILFunction &context) const {
4853+ // Most of the checks here are symmetric, but for those that aren't,
4854+ // the question is whether the ABI makes it safe to use a value of
4855+ // this type as if it had type `other`.
4856+
48424857 // The calling convention and function representation can't be changed.
48434858 if (getRepresentation () != other->getRepresentation ())
48444859 return ABICompatibilityCheckResult::DifferentFunctionRepresentations;
@@ -4853,8 +4868,8 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other,
48534868 }
48544869
48554870 // @isolated(any) imposes an additional requirement on the context
4856- // storage and cannot be added.
4857- if (other->hasErasedIsolation () != hasErasedIsolation ())
4871+ // storage and cannot be added. It can safely be removed, however.
4872+ if (other->hasErasedIsolation () && ! hasErasedIsolation ())
48584873 return ABICompatibilityCheckResult::DifferentErasedIsolation;
48594874
48604875 // Check the results.
@@ -4908,11 +4923,14 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other,
49084923
49094924 if (param1.getConvention () != param2.getConvention ())
49104925 return {ABICompatibilityCheckResult::DifferingParameterConvention, i};
4926+ // Note that the diretionality here is reversed from the other cases
4927+ // because of contravariance: parameters of the *second* type will be
4928+ // trivially converted to be parameters of the *first* type.
49114929 if (!areABICompatibleParamsOrReturns (
4912- param1.getSILStorageType (context.getModule (), this ,
4913- context.getTypeExpansionContext ()),
49144930 param2.getSILStorageType (context.getModule (), other,
49154931 context.getTypeExpansionContext ()),
4932+ param1.getSILStorageType (context.getModule (), this ,
4933+ context.getTypeExpansionContext ()),
49164934 &context))
49174935 return {ABICompatibilityCheckResult::ABIIncompatibleParameterType, i};
49184936 }
0 commit comments