@@ -93,7 +93,7 @@ static CanType unwrapExistential(CanType e) {
93
93
// / into an existential type by performing a static check
94
94
// / of protocol conformances if it is possible.
95
95
static DynamicCastFeasibility
96
- classifyDynamicCastToProtocol (CanType source, CanType target,
96
+ classifyDynamicCastToProtocol (SILFunction *function, CanType source, CanType target,
97
97
bool isWholeModuleOpts) {
98
98
assert (target.isExistentialType () &&
99
99
" target should be an existential type" );
@@ -115,8 +115,12 @@ classifyDynamicCastToProtocol(CanType source, CanType target,
115
115
116
116
// If checkConformance() returns a valid conformance, then all conditional
117
117
// 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
+
119
122
return DynamicCastFeasibility::WillSucceed;
123
+ }
120
124
121
125
auto *SourceNominalTy = source.getAnyNominal ();
122
126
if (!SourceNominalTy)
@@ -468,7 +472,7 @@ static bool isCFBridgingConversion(CanType sourceFormalType,
468
472
469
473
// / Try to classify the dynamic-cast relationship between two types.
470
474
DynamicCastFeasibility
471
- swift::classifyDynamicCast (ModuleDecl *M ,
475
+ swift::classifyDynamicCast (SILFunction *function ,
472
476
CanType source,
473
477
CanType target,
474
478
bool isSourceTypeExact,
@@ -481,19 +485,20 @@ swift::classifyDynamicCast(ModuleDecl *M,
481
485
482
486
auto sourceObject = source.getOptionalObjectType ();
483
487
auto targetObject = target.getOptionalObjectType ();
488
+ ModuleDecl *M = function->getModule ().getSwiftModule ();
484
489
485
490
// A common level of optionality doesn't affect the feasibility,
486
491
// except that we can't fold things to failure because nil inhabits
487
492
// both types.
488
493
if (sourceObject && targetObject) {
489
- return atWorst (classifyDynamicCast (M , sourceObject, targetObject),
494
+ return atWorst (classifyDynamicCast (function , sourceObject, targetObject),
490
495
DynamicCastFeasibility::MaySucceed);
491
496
492
497
// Casting to a more optional type follows the same rule unless we
493
498
// know that the source cannot dynamically be an optional value,
494
499
// in which case we'll always just cast and inject into an optional.
495
500
} else if (targetObject) {
496
- auto result = classifyDynamicCast (M , source, targetObject,
501
+ auto result = classifyDynamicCast (function , source, targetObject,
497
502
/* isSourceTypeExact */ false ,
498
503
isWholeModuleOpts);
499
504
if (canDynamicallyStoreOptional (source))
@@ -502,12 +507,12 @@ swift::classifyDynamicCast(ModuleDecl *M,
502
507
503
508
// Casting to a less-optional type can always fail.
504
509
} else if (sourceObject) {
505
- auto result = atBest (classifyDynamicCast (M , sourceObject, target,
510
+ auto result = atBest (classifyDynamicCast (function , sourceObject, target,
506
511
/* isSourceTypeExact */ false ,
507
512
isWholeModuleOpts),
508
513
DynamicCastFeasibility::MaySucceed);
509
514
if (target.isExistentialType ()) {
510
- result = atWorst (result, classifyDynamicCastToProtocol (
515
+ result = atWorst (result, classifyDynamicCastToProtocol (function,
511
516
source, target, isWholeModuleOpts));
512
517
}
513
518
return result;
@@ -522,7 +527,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
522
527
// Check conversions from non-protocol types into protocol types.
523
528
if (!source.isExistentialType () &&
524
529
target.isExistentialType ())
525
- return classifyDynamicCastToProtocol (source, target,
530
+ return classifyDynamicCastToProtocol (function, source, target,
526
531
isWholeModuleOpts);
527
532
528
533
// Check conversions from protocol types to non-protocol types.
@@ -552,7 +557,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
552
557
// Hashable is not actually a legal existential type right now, but
553
558
// the check doesn't care about that.
554
559
if (auto hashable = getHashableExistentialType (M)) {
555
- return classifyDynamicCastToProtocol (source, hashable,
560
+ return classifyDynamicCastToProtocol (function, source, hashable,
556
561
isWholeModuleOpts);
557
562
}
558
563
}
@@ -589,7 +594,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
589
594
590
595
if (targetMetatype.isAnyExistentialType () && target->isExistentialType ()) {
591
596
auto Feasibility =
592
- classifyDynamicCastToProtocol (source, target, isWholeModuleOpts);
597
+ classifyDynamicCastToProtocol (function, source, target, isWholeModuleOpts);
593
598
// Cast from existential metatype to existential metatype may still
594
599
// succeed, even if we cannot prove anything statically.
595
600
if (Feasibility != DynamicCastFeasibility::WillFail ||
@@ -699,7 +704,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
699
704
700
705
// Combine the result of prior elements with this element type.
701
706
result = std::max (result,
702
- classifyDynamicCast (M ,
707
+ classifyDynamicCast (function ,
703
708
sourceElt.getType ()->getCanonicalType (),
704
709
targetElt.getType ()->getCanonicalType (),
705
710
isSourceTypeExact,
@@ -758,7 +763,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
758
763
// question there.
759
764
if (bridgedSource) source = bridgedSource;
760
765
if (bridgedTarget) target = bridgedTarget;
761
- return classifyDynamicCast (M , source, target, false , isWholeModuleOpts);
766
+ return classifyDynamicCast (function , source, target, false , isWholeModuleOpts);
762
767
}
763
768
764
769
// Casts from a class into a non-class can never succeed if the target must
@@ -833,7 +838,7 @@ swift::classifyDynamicCast(ModuleDecl *M,
833
838
if (Type ObjCTy = M->getASTContext ().getBridgedToObjC (M, source)) {
834
839
// If the bridged ObjC type is known, check if
835
840
// this type can be cast into target type.
836
- return classifyDynamicCast (M ,
841
+ return classifyDynamicCast (function ,
837
842
ObjCTy->getCanonicalType (),
838
843
target,
839
844
/* isSourceTypeExact */ false , isWholeModuleOpts);
@@ -861,16 +866,16 @@ swift::classifyDynamicCast(ModuleDecl *M,
861
866
// Arrays and sets.
862
867
if (sourceStruct->isArray () || sourceStruct->isSet ()) {
863
868
auto valueFeasibility =
864
- classifyDynamicCast (M , sourceArgs[0 ], targetArgs[0 ]);
869
+ classifyDynamicCast (function , sourceArgs[0 ], targetArgs[0 ]);
865
870
return atWorst (valueFeasibility,
866
871
DynamicCastFeasibility::MaySucceed);
867
872
868
873
// Dictionaries.
869
874
} else if (sourceStruct->isDictionary ()) {
870
875
auto keyFeasibility =
871
- classifyDynamicCast (M , sourceArgs[0 ], targetArgs[0 ]);
876
+ classifyDynamicCast (function , sourceArgs[0 ], targetArgs[0 ]);
872
877
auto valueFeasibility =
873
- classifyDynamicCast (M , sourceArgs[1 ], targetArgs[1 ]);
878
+ classifyDynamicCast (function , sourceArgs[1 ], targetArgs[1 ]);
874
879
return atWorst (atBest (keyFeasibility, valueFeasibility),
875
880
DynamicCastFeasibility::MaySucceed);
876
881
}
@@ -881,6 +886,25 @@ swift::classifyDynamicCast(ModuleDecl *M,
881
886
return DynamicCastFeasibility::WillFail;
882
887
}
883
888
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
+
884
908
static unsigned getOptionalDepth (CanType type) {
885
909
unsigned depth = 0 ;
886
910
while (CanType objectType = type.getOptionalObjectType ()) {
@@ -1221,7 +1245,7 @@ swift::emitSuccessfulScalarUnconditionalCast(SILBuilder &B, ModuleDecl *M,
1221
1245
CanType sourceFormalType,
1222
1246
CanType targetFormalType,
1223
1247
SILInstruction *existingCast) {
1224
- assert (classifyDynamicCast (M , sourceFormalType, targetFormalType)
1248
+ assert (classifyDynamicCast (&B. getFunction () , sourceFormalType, targetFormalType)
1225
1249
== DynamicCastFeasibility::WillSucceed);
1226
1250
1227
1251
// Casts to/from existential types cannot be further improved.
@@ -1258,7 +1282,7 @@ bool swift::emitSuccessfulIndirectUnconditionalCast(
1258
1282
SILBuilder &B, ModuleDecl *M, SILLocation loc, SILValue src,
1259
1283
CanType sourceFormalType, SILValue dest, CanType targetFormalType,
1260
1284
SILInstruction *existingCast) {
1261
- assert (classifyDynamicCast (M , sourceFormalType, targetFormalType)
1285
+ assert (classifyDynamicCast (&B. getFunction () , sourceFormalType, targetFormalType)
1262
1286
== DynamicCastFeasibility::WillSucceed);
1263
1287
1264
1288
assert (src->getType ().isAddress ());
0 commit comments