@@ -2839,6 +2839,29 @@ namespace {
2839
2839
}
2840
2840
}
2841
2841
2842
+ // / Function object that refines isolation for each actor isolation it is
2843
+ // / given, returning true if all of the provided isolations have been
2844
+ // / accounted for, or false if the caller should handle them.
2845
+ class RefineConformances {
2846
+ ActorIsolationChecker &self;
2847
+
2848
+ public:
2849
+ RefineConformances (ActorIsolationChecker &self) : self(self) { }
2850
+
2851
+ bool operator ()(ArrayRef<ActorIsolation> isolations) const {
2852
+ bool anyRefined = false ;
2853
+ bool anyUnrefined = false ;
2854
+ for (const auto &isolation : isolations) {
2855
+ if (self.refineRequiredIsolation (isolation))
2856
+ anyRefined = true ;
2857
+ else
2858
+ anyUnrefined = true ;
2859
+ }
2860
+
2861
+ return anyRefined && !anyUnrefined;
2862
+ }
2863
+ };
2864
+
2842
2865
bool refineRequiredIsolation (ActorIsolation refinedIsolation) {
2843
2866
if (requiredIsolationLoc.isInvalid ())
2844
2867
return false ;
@@ -3348,13 +3371,13 @@ namespace {
3348
3371
if (auto erasureExpr = dyn_cast<ErasureExpr>(expr)) {
3349
3372
checkIsolatedConformancesInContext (
3350
3373
erasureExpr->getConformances (), erasureExpr->getLoc (),
3351
- getDeclContext ());
3374
+ getDeclContext (), RefineConformances{* this } );
3352
3375
}
3353
3376
3354
3377
if (auto *underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
3355
3378
checkIsolatedConformancesInContext (
3356
3379
underlyingToOpaque->substitutions , underlyingToOpaque->getLoc (),
3357
- getDeclContext ());
3380
+ getDeclContext (), RefineConformances{* this } );
3358
3381
}
3359
3382
3360
3383
return Action::Continue (expr);
@@ -4463,7 +4486,8 @@ namespace {
4463
4486
return false ;
4464
4487
4465
4488
// Make sure isolated conformances are formed in the right context.
4466
- checkIsolatedConformancesInContext (declRef, loc, getDeclContext ());
4489
+ checkIsolatedConformancesInContext (declRef, loc, getDeclContext (),
4490
+ RefineConformances{*this });
4467
4491
4468
4492
auto *const decl = declRef.getDecl ();
4469
4493
@@ -8039,11 +8063,14 @@ namespace {
8039
8063
class MismatchedIsolatedConformances {
8040
8064
llvm::TinyPtrVector<ProtocolConformance *> badIsolatedConformances;
8041
8065
DeclContext *fromDC;
8066
+ HandleConformanceIsolationFn handleBad;
8042
8067
mutable std::optional<ActorIsolation> fromIsolation;
8043
8068
8044
8069
public:
8045
- MismatchedIsolatedConformances (const DeclContext *fromDC)
8046
- : fromDC(const_cast <DeclContext *>(fromDC)) { }
8070
+ MismatchedIsolatedConformances (const DeclContext *fromDC,
8071
+ HandleConformanceIsolationFn handleBad)
8072
+ : fromDC(const_cast <DeclContext *>(fromDC)),
8073
+ handleBad (handleBad) { }
8047
8074
8048
8075
ActorIsolation getContextIsolation () const {
8049
8076
if (!fromIsolation)
@@ -8083,6 +8110,16 @@ namespace {
8083
8110
if (badIsolatedConformances.empty ())
8084
8111
return false ;
8085
8112
8113
+ if (handleBad) {
8114
+ // Capture all of the actor isolations from the conformances.
8115
+ std::vector<ActorIsolation> badIsolations;
8116
+ for (auto conformance : badIsolatedConformances)
8117
+ badIsolations.push_back (conformance->getIsolation ());
8118
+
8119
+ if (handleBad (badIsolations))
8120
+ return false ;
8121
+ }
8122
+
8086
8123
ASTContext &ctx = fromDC->getASTContext ();
8087
8124
auto firstConformance = badIsolatedConformances.front ();
8088
8125
ctx.Diags .diagnose (
@@ -8098,32 +8135,40 @@ namespace {
8098
8135
8099
8136
}
8100
8137
8138
+ bool swift::doNotDiagnoseConformanceIsolation (ArrayRef<ActorIsolation>) {
8139
+ return false ;
8140
+ }
8141
+
8101
8142
bool swift::checkIsolatedConformancesInContext (
8102
- ConcreteDeclRef declRef, SourceLoc loc, const DeclContext *dc) {
8103
- MismatchedIsolatedConformances mismatched (dc);
8143
+ ConcreteDeclRef declRef, SourceLoc loc, const DeclContext *dc,
8144
+ HandleConformanceIsolationFn handleBad) {
8145
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8104
8146
forEachConformance (declRef, mismatched);
8105
8147
return mismatched.diagnose (loc);
8106
8148
}
8107
8149
8108
8150
bool swift::checkIsolatedConformancesInContext (
8109
8151
ArrayRef<ProtocolConformanceRef> conformances, SourceLoc loc,
8110
- const DeclContext *dc) {
8111
- MismatchedIsolatedConformances mismatched (dc);
8152
+ const DeclContext *dc,
8153
+ HandleConformanceIsolationFn handleBad) {
8154
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8112
8155
for (auto conformance: conformances)
8113
8156
forEachConformance (conformance, mismatched);
8114
8157
return mismatched.diagnose (loc);
8115
8158
}
8116
8159
8117
8160
bool swift::checkIsolatedConformancesInContext (
8118
- SubstitutionMap subs, SourceLoc loc, const DeclContext *dc) {
8119
- MismatchedIsolatedConformances mismatched (dc);
8161
+ SubstitutionMap subs, SourceLoc loc, const DeclContext *dc,
8162
+ HandleConformanceIsolationFn handleBad) {
8163
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8120
8164
forEachConformance (subs, mismatched);
8121
8165
return mismatched.diagnose (loc);
8122
8166
}
8123
8167
8124
8168
bool swift::checkIsolatedConformancesInContext (
8125
- Type type, SourceLoc loc, const DeclContext *dc) {
8126
- MismatchedIsolatedConformances mismatched (dc);
8169
+ Type type, SourceLoc loc, const DeclContext *dc,
8170
+ HandleConformanceIsolationFn handleBad) {
8171
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8127
8172
forEachConformance (type, mismatched);
8128
8173
return mismatched.diagnose (loc);
8129
8174
}
0 commit comments