@@ -5936,6 +5936,65 @@ static void addAttributesForActorIsolation(ValueDecl *value,
59365936 }
59375937}
59385938
5939+ // / Determine whether there is a SendableMetatype conformance that requires that the nominal type
5940+ // / be nonisolated (preventing @MainActor inference).
5941+ static bool sendableConformanceRequiresNonisolated (NominalTypeDecl *nominal) {
5942+ ASTContext &ctx = nominal->getASTContext ();
5943+ if (!ctx.LangOpts .hasFeature (Feature::SendableProhibitsMainActorInference))
5944+ return false ;
5945+
5946+ if (isa<ProtocolDecl>(nominal))
5947+ return false ;
5948+
5949+ auto sendable = ctx.getProtocol (KnownProtocolKind::Sendable);
5950+ auto sendableMetatype = ctx.getProtocol (KnownProtocolKind::SendableMetatype);
5951+ if (!sendableMetatype)
5952+ return false ;
5953+
5954+ // Check whether any of the explicit conformances is to a
5955+ // SendableMetatype-inheriting protocol. We exclude direct conformance to
5956+ // Sendable here, because a global-actor-isolated type is implicitly Sendable,
5957+ // and writing Sendable explicitly
5958+ InvertibleProtocolSet inverses;
5959+ bool anyObject = false ;
5960+ auto inherited = getDirectlyInheritedNominalTypeDecls (
5961+ nominal, inverses, anyObject);
5962+ for (const auto &entry : inherited) {
5963+ auto proto = dyn_cast<ProtocolDecl>(entry.Item );
5964+ if (proto && proto != sendable && proto->inheritsFrom (sendableMetatype))
5965+ return true ;
5966+ }
5967+
5968+ // Check for member or extension macros that define conformances to
5969+ // SendableMetatype-inheriting protocols.
5970+ bool requiresNonisolated = false ;
5971+ auto checkMacro = [&](MacroRole role, MacroDecl *macro) {
5972+ if (!macro || requiresNonisolated)
5973+ return ;
5974+
5975+ SmallVector<ProtocolDecl *, 2 > conformances;
5976+ macro->getIntroducedConformances (nominal, role, conformances);
5977+ for (auto proto : conformances) {
5978+ if (proto == sendableMetatype || proto->inheritsFrom (sendableMetatype)) {
5979+ requiresNonisolated = true ;
5980+ break ;
5981+ }
5982+ }
5983+ };
5984+
5985+ nominal->forEachAttachedMacro (
5986+ MacroRole::Member,
5987+ [&](CustomAttr * attr, MacroDecl *macro) {
5988+ checkMacro (MacroRole::Member, macro);
5989+ });
5990+ nominal->forEachAttachedMacro (
5991+ MacroRole::Extension,
5992+ [&](CustomAttr * attr, MacroDecl *macro) {
5993+ checkMacro (MacroRole::Extension, macro);
5994+ });
5995+ return requiresNonisolated;
5996+ }
5997+
59395998// / Determine the default isolation and isolation source for this declaration,
59405999// / which may still be overridden by other inference rules.
59416000static std::tuple<InferredActorIsolation, ValueDecl *,
@@ -5955,24 +6014,34 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
59556014 auto *dc = value->getInnermostDeclContext ();
59566015 while (dc && !inActorContext) {
59576016 if (auto *nominal = dc->getSelfNominalTypeDecl ()) {
5958- inActorContext = nominal->isAnyActor ();
6017+ if (nominal->isAnyActor ())
6018+ return {};
59596019 }
59606020 dc = dc->getParent ();
59616021 }
59626022
5963- if (!inActorContext) {
5964- // FIXME: deinit should be implicitly MainActor too.
5965- if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5966- isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5967- isa<ConstructorDecl>(value)) {
6023+ // If this is or is a non-type member of a nominal type that conforms to a
6024+ // SendableMetatype-inheriting protocol in its primary definition, disable
6025+ // @MainActor inference.
6026+ auto nominalTypeDecl = dyn_cast<NominalTypeDecl>(value);
6027+ if (!nominalTypeDecl && !isa<TypeDecl>(value)) {
6028+ nominalTypeDecl = value->getDeclContext ()->getSelfNominalTypeDecl ();
6029+ }
6030+ if (nominalTypeDecl &&
6031+ sendableConformanceRequiresNonisolated (nominalTypeDecl))
6032+ return { };
6033+
6034+ // FIXME: deinit should be implicitly MainActor too.
6035+ if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
6036+ isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
6037+ isa<ConstructorDecl>(value)) {
59686038 // Preconcurrency here is used to stage the diagnostics
59696039 // when users select `@MainActor` default isolation with
59706040 // non-strict concurrency modes (pre Swift 6).
59716041 auto isolation =
59726042 ActorIsolation::forGlobalActor (globalActor)
59736043 .withPreconcurrency (!ctx.LangOpts .isSwiftVersionAtLeast (6 ));
59746044 return {{{isolation, {}}, nullptr , {}}};
5975- }
59766045 }
59776046
59786047 return {};
0 commit comments