@@ -93,7 +93,7 @@ static CanType unwrapExistential(CanType e) {
9393// / into an existential type by performing a static check
9494// / of protocol conformances if it is possible.
9595static DynamicCastFeasibility
96- classifyDynamicCastToProtocol (CanType source, CanType target,
96+ classifyDynamicCastToProtocol (SILFunction *function, CanType source, CanType target,
9797 bool isWholeModuleOpts) {
9898 assert (target.isExistentialType () &&
9999 " target should be an existential type" );
@@ -115,8 +115,12 @@ classifyDynamicCastToProtocol(CanType source, CanType target,
115115
116116 // If checkConformance() returns a valid conformance, then all conditional
117117 // requirements were satisfied.
118- if (checkConformance (source, TargetProtocol))
118+ if (auto conformance = checkConformance (source, TargetProtocol)) {
119+ if (!matchesActorIsolation (conformance, function))
120+ return DynamicCastFeasibility::MaySucceed;
121+
119122 return DynamicCastFeasibility::WillSucceed;
123+ }
120124
121125 auto *SourceNominalTy = source.getAnyNominal ();
122126 if (!SourceNominalTy)
@@ -468,7 +472,7 @@ static bool isCFBridgingConversion(CanType sourceFormalType,
468472
469473// / Try to classify the dynamic-cast relationship between two types.
470474DynamicCastFeasibility
471- swift::classifyDynamicCast (ModuleDecl *M ,
475+ swift::classifyDynamicCast (SILFunction *function ,
472476 CanType source,
473477 CanType target,
474478 bool isSourceTypeExact,
@@ -481,19 +485,20 @@ swift::classifyDynamicCast(ModuleDecl *M,
481485
482486 auto sourceObject = source.getOptionalObjectType ();
483487 auto targetObject = target.getOptionalObjectType ();
488+ ModuleDecl *M = function->getModule ().getSwiftModule ();
484489
485490 // A common level of optionality doesn't affect the feasibility,
486491 // except that we can't fold things to failure because nil inhabits
487492 // both types.
488493 if (sourceObject && targetObject) {
489- return atWorst (classifyDynamicCast (M , sourceObject, targetObject),
494+ return atWorst (classifyDynamicCast (function , sourceObject, targetObject),
490495 DynamicCastFeasibility::MaySucceed);
491496
492497 // Casting to a more optional type follows the same rule unless we
493498 // know that the source cannot dynamically be an optional value,
494499 // in which case we'll always just cast and inject into an optional.
495500 } else if (targetObject) {
496- auto result = classifyDynamicCast (M , source, targetObject,
501+ auto result = classifyDynamicCast (function , source, targetObject,
497502 /* isSourceTypeExact */ false ,
498503 isWholeModuleOpts);
499504 if (canDynamicallyStoreOptional (source))
@@ -502,12 +507,12 @@ swift::classifyDynamicCast(ModuleDecl *M,
502507
503508 // Casting to a less-optional type can always fail.
504509 } else if (sourceObject) {
505- auto result = atBest (classifyDynamicCast (M , sourceObject, target,
510+ auto result = atBest (classifyDynamicCast (function , sourceObject, target,
506511 /* isSourceTypeExact */ false ,
507512 isWholeModuleOpts),
508513 DynamicCastFeasibility::MaySucceed);
509514 if (target.isExistentialType ()) {
510- result = atWorst (result, classifyDynamicCastToProtocol (
515+ result = atWorst (result, classifyDynamicCastToProtocol (function,
511516 source, target, isWholeModuleOpts));
512517 }
513518 return result;
@@ -522,7 +527,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
522527 // Check conversions from non-protocol types into protocol types.
523528 if (!source.isExistentialType () &&
524529 target.isExistentialType ())
525- return classifyDynamicCastToProtocol (source, target,
530+ return classifyDynamicCastToProtocol (function, source, target,
526531 isWholeModuleOpts);
527532
528533 // Check conversions from protocol types to non-protocol types.
@@ -552,7 +557,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
552557 // Hashable is not actually a legal existential type right now, but
553558 // the check doesn't care about that.
554559 if (auto hashable = getHashableExistentialType (M)) {
555- return classifyDynamicCastToProtocol (source, hashable,
560+ return classifyDynamicCastToProtocol (function, source, hashable,
556561 isWholeModuleOpts);
557562 }
558563 }
@@ -589,7 +594,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
589594
590595 if (targetMetatype.isAnyExistentialType () && target->isExistentialType ()) {
591596 auto Feasibility =
592- classifyDynamicCastToProtocol (source, target, isWholeModuleOpts);
597+ classifyDynamicCastToProtocol (function, source, target, isWholeModuleOpts);
593598 // Cast from existential metatype to existential metatype may still
594599 // succeed, even if we cannot prove anything statically.
595600 if (Feasibility != DynamicCastFeasibility::WillFail ||
@@ -699,7 +704,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
699704
700705 // Combine the result of prior elements with this element type.
701706 result = std::max (result,
702- classifyDynamicCast (M ,
707+ classifyDynamicCast (function ,
703708 sourceElt.getType ()->getCanonicalType (),
704709 targetElt.getType ()->getCanonicalType (),
705710 isSourceTypeExact,
@@ -758,7 +763,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
758763 // question there.
759764 if (bridgedSource) source = bridgedSource;
760765 if (bridgedTarget) target = bridgedTarget;
761- return classifyDynamicCast (M , source, target, false , isWholeModuleOpts);
766+ return classifyDynamicCast (function , source, target, false , isWholeModuleOpts);
762767 }
763768
764769 // Casts from a class into a non-class can never succeed if the target must
@@ -833,7 +838,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
833838 if (Type ObjCTy = M->getASTContext ().getBridgedToObjC (M, source)) {
834839 // If the bridged ObjC type is known, check if
835840 // this type can be cast into target type.
836- return classifyDynamicCast (M ,
841+ return classifyDynamicCast (function ,
837842 ObjCTy->getCanonicalType (),
838843 target,
839844 /* isSourceTypeExact */ false , isWholeModuleOpts);
@@ -861,16 +866,16 @@ swift::classifyDynamicCast(ModuleDecl *M,
861866 // Arrays and sets.
862867 if (sourceStruct->isArray () || sourceStruct->isSet ()) {
863868 auto valueFeasibility =
864- classifyDynamicCast (M , sourceArgs[0 ], targetArgs[0 ]);
869+ classifyDynamicCast (function , sourceArgs[0 ], targetArgs[0 ]);
865870 return atWorst (valueFeasibility,
866871 DynamicCastFeasibility::MaySucceed);
867872
868873 // Dictionaries.
869874 } else if (sourceStruct->isDictionary ()) {
870875 auto keyFeasibility =
871- classifyDynamicCast (M , sourceArgs[0 ], targetArgs[0 ]);
876+ classifyDynamicCast (function , sourceArgs[0 ], targetArgs[0 ]);
872877 auto valueFeasibility =
873- classifyDynamicCast (M , sourceArgs[1 ], targetArgs[1 ]);
878+ classifyDynamicCast (function , sourceArgs[1 ], targetArgs[1 ]);
874879 return atWorst (atBest (keyFeasibility, valueFeasibility),
875880 DynamicCastFeasibility::MaySucceed);
876881 }
@@ -881,6 +886,25 @@ swift::classifyDynamicCast(ModuleDecl *M,
881886 return DynamicCastFeasibility::WillFail;
882887}
883888
889+ bool swift::matchesActorIsolation (ProtocolConformanceRef conformance, SILFunction *inFunction) {
890+ return !conformance.forEachIsolatedConformance ([&](ProtocolConformanceRef isolatedConf) -> bool {
891+ if (!isolatedConf.isConcrete ())
892+ return false ;
893+
894+ ActorIsolation isolation = isolatedConf.getConcrete ()->getIsolation ();
895+ if (isolation.isNonisolated ())
896+ return false ;
897+
898+ if (isolation.isGlobalActor ()) {
899+ if (auto functionIsolation = inFunction->getActorIsolation ()) {
900+ if (isolation == functionIsolation.value ())
901+ return false ;
902+ }
903+ }
904+ return true ;
905+ });
906+ }
907+
884908static unsigned getOptionalDepth (CanType type) {
885909 unsigned depth = 0 ;
886910 while (CanType objectType = type.getOptionalObjectType ()) {
@@ -1221,7 +1245,7 @@ swift::emitSuccessfulScalarUnconditionalCast(SILBuilder &B, ModuleDecl *M,
12211245 CanType sourceFormalType,
12221246 CanType targetFormalType,
12231247 SILInstruction *existingCast) {
1224- assert (classifyDynamicCast (M , sourceFormalType, targetFormalType)
1248+ assert (classifyDynamicCast (&B. getFunction () , sourceFormalType, targetFormalType)
12251249 == DynamicCastFeasibility::WillSucceed);
12261250
12271251 // Casts to/from existential types cannot be further improved.
@@ -1258,7 +1282,7 @@ bool swift::emitSuccessfulIndirectUnconditionalCast(
12581282 SILBuilder &B, ModuleDecl *M, SILLocation loc, SILValue src,
12591283 CanType sourceFormalType, SILValue dest, CanType targetFormalType,
12601284 SILInstruction *existingCast) {
1261- assert (classifyDynamicCast (M , sourceFormalType, targetFormalType)
1285+ assert (classifyDynamicCast (&B. getFunction () , sourceFormalType, targetFormalType)
12621286 == DynamicCastFeasibility::WillSucceed);
12631287
12641288 assert (src->getType ().isAddress ());
0 commit comments