@@ -2839,6 +2839,29 @@ namespace {
28392839 }
28402840 }
28412841
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+
28422865 bool refineRequiredIsolation (ActorIsolation refinedIsolation) {
28432866 if (requiredIsolationLoc.isInvalid ())
28442867 return false ;
@@ -3348,13 +3371,13 @@ namespace {
33483371 if (auto erasureExpr = dyn_cast<ErasureExpr>(expr)) {
33493372 checkIsolatedConformancesInContext (
33503373 erasureExpr->getConformances (), erasureExpr->getLoc (),
3351- getDeclContext ());
3374+ getDeclContext (), RefineConformances{* this } );
33523375 }
33533376
33543377 if (auto *underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
33553378 checkIsolatedConformancesInContext (
33563379 underlyingToOpaque->substitutions , underlyingToOpaque->getLoc (),
3357- getDeclContext ());
3380+ getDeclContext (), RefineConformances{* this } );
33583381 }
33593382
33603383 return Action::Continue (expr);
@@ -4463,7 +4486,8 @@ namespace {
44634486 return false ;
44644487
44654488 // Make sure isolated conformances are formed in the right context.
4466- checkIsolatedConformancesInContext (declRef, loc, getDeclContext ());
4489+ checkIsolatedConformancesInContext (declRef, loc, getDeclContext (),
4490+ RefineConformances{*this });
44674491
44684492 auto *const decl = declRef.getDecl ();
44694493
@@ -8039,11 +8063,14 @@ namespace {
80398063 class MismatchedIsolatedConformances {
80408064 llvm::TinyPtrVector<ProtocolConformance *> badIsolatedConformances;
80418065 DeclContext *fromDC;
8066+ HandleConformanceIsolationFn handleBad;
80428067 mutable std::optional<ActorIsolation> fromIsolation;
80438068
80448069 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) { }
80478074
80488075 ActorIsolation getContextIsolation () const {
80498076 if (!fromIsolation)
@@ -8083,6 +8110,16 @@ namespace {
80838110 if (badIsolatedConformances.empty ())
80848111 return false ;
80858112
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+
80868123 ASTContext &ctx = fromDC->getASTContext ();
80878124 auto firstConformance = badIsolatedConformances.front ();
80888125 ctx.Diags .diagnose (
@@ -8098,32 +8135,40 @@ namespace {
80988135
80998136}
81008137
8138+ bool swift::doNotDiagnoseConformanceIsolation (ArrayRef<ActorIsolation>) {
8139+ return false ;
8140+ }
8141+
81018142bool 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);
81048146 forEachConformance (declRef, mismatched);
81058147 return mismatched.diagnose (loc);
81068148}
81078149
81088150bool swift::checkIsolatedConformancesInContext (
81098151 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);
81128155 for (auto conformance: conformances)
81138156 forEachConformance (conformance, mismatched);
81148157 return mismatched.diagnose (loc);
81158158}
81168159
81178160bool 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);
81208164 forEachConformance (subs, mismatched);
81218165 return mismatched.diagnose (loc);
81228166}
81238167
81248168bool 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);
81278172 forEachConformance (type, mismatched);
81288173 return mismatched.diagnose (loc);
81298174}
0 commit comments