@@ -2823,6 +2823,29 @@ namespace {
2823
2823
}
2824
2824
}
2825
2825
2826
+ // / Function object that refines isolation for each actor isolation it is
2827
+ // / given, returning true if all of the provided isolations have been
2828
+ // / accounted for, or false if the caller should handle them.
2829
+ class RefineConformances {
2830
+ ActorIsolationChecker &self;
2831
+
2832
+ public:
2833
+ RefineConformances (ActorIsolationChecker &self) : self(self) { }
2834
+
2835
+ bool operator ()(ArrayRef<ActorIsolation> isolations) const {
2836
+ bool anyRefined = false ;
2837
+ bool anyUnrefined = false ;
2838
+ for (const auto &isolation : isolations) {
2839
+ if (self.refineRequiredIsolation (isolation))
2840
+ anyRefined = true ;
2841
+ else
2842
+ anyUnrefined = true ;
2843
+ }
2844
+
2845
+ return anyRefined && !anyUnrefined;
2846
+ }
2847
+ };
2848
+
2826
2849
bool refineRequiredIsolation (ActorIsolation refinedIsolation) {
2827
2850
if (requiredIsolationLoc.isInvalid ())
2828
2851
return false ;
@@ -3332,13 +3355,13 @@ namespace {
3332
3355
if (auto erasureExpr = dyn_cast<ErasureExpr>(expr)) {
3333
3356
checkIsolatedConformancesInContext (
3334
3357
erasureExpr->getConformances (), erasureExpr->getLoc (),
3335
- getDeclContext ());
3358
+ getDeclContext (), RefineConformances{* this } );
3336
3359
}
3337
3360
3338
3361
if (auto *underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
3339
3362
checkIsolatedConformancesInContext (
3340
3363
underlyingToOpaque->substitutions , underlyingToOpaque->getLoc (),
3341
- getDeclContext ());
3364
+ getDeclContext (), RefineConformances{* this } );
3342
3365
}
3343
3366
3344
3367
return Action::Continue (expr);
@@ -4447,7 +4470,8 @@ namespace {
4447
4470
return false ;
4448
4471
4449
4472
// Make sure isolated conformances are formed in the right context.
4450
- checkIsolatedConformancesInContext (declRef, loc, getDeclContext ());
4473
+ checkIsolatedConformancesInContext (declRef, loc, getDeclContext (),
4474
+ RefineConformances{*this });
4451
4475
4452
4476
auto *const decl = declRef.getDecl ();
4453
4477
@@ -8015,11 +8039,14 @@ namespace {
8015
8039
class MismatchedIsolatedConformances {
8016
8040
llvm::TinyPtrVector<ProtocolConformance *> badIsolatedConformances;
8017
8041
DeclContext *fromDC;
8042
+ HandleConformanceIsolationFn handleBad;
8018
8043
mutable std::optional<ActorIsolation> fromIsolation;
8019
8044
8020
8045
public:
8021
- MismatchedIsolatedConformances (const DeclContext *fromDC)
8022
- : fromDC(const_cast <DeclContext *>(fromDC)) { }
8046
+ MismatchedIsolatedConformances (const DeclContext *fromDC,
8047
+ HandleConformanceIsolationFn handleBad)
8048
+ : fromDC(const_cast <DeclContext *>(fromDC)),
8049
+ handleBad (handleBad) { }
8023
8050
8024
8051
ActorIsolation getContextIsolation () const {
8025
8052
if (!fromIsolation)
@@ -8059,6 +8086,16 @@ namespace {
8059
8086
if (badIsolatedConformances.empty ())
8060
8087
return false ;
8061
8088
8089
+ if (handleBad) {
8090
+ // Capture all of the actor isolations from the conformances.
8091
+ std::vector<ActorIsolation> badIsolations;
8092
+ for (auto conformance : badIsolatedConformances)
8093
+ badIsolations.push_back (conformance->getIsolation ());
8094
+
8095
+ if (handleBad (badIsolations))
8096
+ return false ;
8097
+ }
8098
+
8062
8099
ASTContext &ctx = fromDC->getASTContext ();
8063
8100
auto firstConformance = badIsolatedConformances.front ();
8064
8101
ctx.Diags .diagnose (
@@ -8074,32 +8111,40 @@ namespace {
8074
8111
8075
8112
}
8076
8113
8114
+ bool swift::doNotDiagnoseConformanceIsolation (ArrayRef<ActorIsolation>) {
8115
+ return false ;
8116
+ }
8117
+
8077
8118
bool swift::checkIsolatedConformancesInContext (
8078
- ConcreteDeclRef declRef, SourceLoc loc, const DeclContext *dc) {
8079
- MismatchedIsolatedConformances mismatched (dc);
8119
+ ConcreteDeclRef declRef, SourceLoc loc, const DeclContext *dc,
8120
+ HandleConformanceIsolationFn handleBad) {
8121
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8080
8122
forEachConformance (declRef, mismatched);
8081
8123
return mismatched.diagnose (loc);
8082
8124
}
8083
8125
8084
8126
bool swift::checkIsolatedConformancesInContext (
8085
8127
ArrayRef<ProtocolConformanceRef> conformances, SourceLoc loc,
8086
- const DeclContext *dc) {
8087
- MismatchedIsolatedConformances mismatched (dc);
8128
+ const DeclContext *dc,
8129
+ HandleConformanceIsolationFn handleBad) {
8130
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8088
8131
for (auto conformance: conformances)
8089
8132
forEachConformance (conformance, mismatched);
8090
8133
return mismatched.diagnose (loc);
8091
8134
}
8092
8135
8093
8136
bool swift::checkIsolatedConformancesInContext (
8094
- SubstitutionMap subs, SourceLoc loc, const DeclContext *dc) {
8095
- MismatchedIsolatedConformances mismatched (dc);
8137
+ SubstitutionMap subs, SourceLoc loc, const DeclContext *dc,
8138
+ HandleConformanceIsolationFn handleBad) {
8139
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8096
8140
forEachConformance (subs, mismatched);
8097
8141
return mismatched.diagnose (loc);
8098
8142
}
8099
8143
8100
8144
bool swift::checkIsolatedConformancesInContext (
8101
- Type type, SourceLoc loc, const DeclContext *dc) {
8102
- MismatchedIsolatedConformances mismatched (dc);
8145
+ Type type, SourceLoc loc, const DeclContext *dc,
8146
+ HandleConformanceIsolationFn handleBad) {
8147
+ MismatchedIsolatedConformances mismatched (dc, handleBad);
8103
8148
forEachConformance (type, mismatched);
8104
8149
return mismatched.diagnose (loc);
8105
8150
}
0 commit comments