@@ -2823,6 +2823,29 @@ namespace {
28232823 }
28242824 }
28252825
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+
28262849 bool refineRequiredIsolation (ActorIsolation refinedIsolation) {
28272850 if (requiredIsolationLoc.isInvalid ())
28282851 return false ;
@@ -3332,13 +3355,13 @@ namespace {
33323355 if (auto erasureExpr = dyn_cast<ErasureExpr>(expr)) {
33333356 checkIsolatedConformancesInContext (
33343357 erasureExpr->getConformances (), erasureExpr->getLoc (),
3335- getDeclContext ());
3358+ getDeclContext (), RefineConformances{* this } );
33363359 }
33373360
33383361 if (auto *underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
33393362 checkIsolatedConformancesInContext (
33403363 underlyingToOpaque->substitutions , underlyingToOpaque->getLoc (),
3341- getDeclContext ());
3364+ getDeclContext (), RefineConformances{* this } );
33423365 }
33433366
33443367 return Action::Continue (expr);
@@ -4447,7 +4470,8 @@ namespace {
44474470 return false ;
44484471
44494472 // Make sure isolated conformances are formed in the right context.
4450- checkIsolatedConformancesInContext (declRef, loc, getDeclContext ());
4473+ checkIsolatedConformancesInContext (declRef, loc, getDeclContext (),
4474+ RefineConformances{*this });
44514475
44524476 auto *const decl = declRef.getDecl ();
44534477
@@ -8015,11 +8039,14 @@ namespace {
80158039 class MismatchedIsolatedConformances {
80168040 llvm::TinyPtrVector<ProtocolConformance *> badIsolatedConformances;
80178041 DeclContext *fromDC;
8042+ HandleConformanceIsolationFn handleBad;
80188043 mutable std::optional<ActorIsolation> fromIsolation;
80198044
80208045 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) { }
80238050
80248051 ActorIsolation getContextIsolation () const {
80258052 if (!fromIsolation)
@@ -8059,6 +8086,16 @@ namespace {
80598086 if (badIsolatedConformances.empty ())
80608087 return false ;
80618088
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+
80628099 ASTContext &ctx = fromDC->getASTContext ();
80638100 auto firstConformance = badIsolatedConformances.front ();
80648101 ctx.Diags .diagnose (
@@ -8074,32 +8111,40 @@ namespace {
80748111
80758112}
80768113
8114+ bool swift::doNotDiagnoseConformanceIsolation (ArrayRef<ActorIsolation>) {
8115+ return false ;
8116+ }
8117+
80778118bool 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);
80808122 forEachConformance (declRef, mismatched);
80818123 return mismatched.diagnose (loc);
80828124}
80838125
80848126bool swift::checkIsolatedConformancesInContext (
80858127 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);
80888131 for (auto conformance: conformances)
80898132 forEachConformance (conformance, mismatched);
80908133 return mismatched.diagnose (loc);
80918134}
80928135
80938136bool 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);
80968140 forEachConformance (subs, mismatched);
80978141 return mismatched.diagnose (loc);
80988142}
80998143
81008144bool 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);
81038148 forEachConformance (type, mismatched);
81048149 return mismatched.diagnose (loc);
81058150}
0 commit comments