@@ -5282,6 +5282,33 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
52825282 llvm_unreachable (" Forgot about an attribute?" );
52835283}
52845284
5285+ // / Determine the default isolation for the given declaration context.
5286+ static DefaultIsolation getDefaultIsolationForContext (const DeclContext *dc) {
5287+ // Check whether there is a file-specific setting.
5288+ if (auto *sourceFile = dc->getParentSourceFile ()) {
5289+ if (auto defaultIsolationInFile = sourceFile->getDefaultIsolation ())
5290+ return defaultIsolationInFile.value ();
5291+ }
5292+
5293+ // If we're in the main module, check the language option.
5294+ ASTContext &ctx = dc->getASTContext ();
5295+ if (dc->getParentModule () == ctx.MainModule )
5296+ return ctx.LangOpts .DefaultIsolationBehavior ;
5297+
5298+ // Otherwise, default to nonisolated.
5299+ return DefaultIsolation::Nonisolated;
5300+ }
5301+
5302+ // / Determines whether explicit 'nonisolated' is different from 'unspecified'
5303+ // / in the given context.
5304+ static bool explicitNonisolatedIsSpecial (const DeclContext *dc) {
5305+ ASTContext &ctx = dc->getASTContext ();
5306+ if (ctx.LangOpts .hasFeature (Feature::NoExplicitNonIsolated))
5307+ return false ;
5308+
5309+ return getDefaultIsolationForContext (dc) == DefaultIsolation::Nonisolated;
5310+ }
5311+
52855312// / Infer isolation from witnessed protocol requirements.
52865313static std::optional<InferredActorIsolation>
52875314getIsolationFromWitnessedRequirements (ValueDecl *value) {
@@ -5298,11 +5325,13 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
52985325 if (dc->getSelfProtocolDecl ())
52995326 return std::nullopt ;
53005327
5301- // Prevent isolation inference from requirements if the conforming type
5302- // has an explicit `nonisolated` attribute.
5303- if (auto *NTD = dc->getSelfNominalTypeDecl ()) {
5304- if (NTD->getAttrs ().hasAttribute <NonisolatedAttr>())
5305- return std::nullopt ;
5328+ if (explicitNonisolatedIsSpecial (dc)) {
5329+ // Prevent isolation inference from requirements if the conforming type
5330+ // has an explicit `nonisolated` attribute.
5331+ if (auto *NTD = dc->getSelfNominalTypeDecl ()) {
5332+ if (NTD->getAttrs ().hasAttribute <NonisolatedAttr>())
5333+ return std::nullopt ;
5334+ }
53065335 }
53075336
53085337 // Walk through each of the conformances in this context, collecting any
@@ -5360,8 +5389,13 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
53605389 }
53615390
53625391 case ActorIsolation::GlobalActor:
5392+ break ;
5393+
53635394 case ActorIsolation::Nonisolated:
53645395 case ActorIsolation::NonisolatedUnsafe:
5396+ if (!explicitNonisolatedIsSpecial (requirement->getDeclContext ()))
5397+ continue ;
5398+
53655399 break ;
53665400 }
53675401
@@ -5468,7 +5502,8 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
54685502 case ActorIsolation::NonisolatedUnsafe:
54695503 break ;
54705504 case ActorIsolation::Nonisolated:
5471- if (inferredIsolation.source .kind == IsolationSource::Kind::Explicit) {
5505+ if (inferredIsolation.source .kind == IsolationSource::Kind::Explicit &&
5506+ explicitNonisolatedIsSpecial (nominal)) {
54725507 if (!foundIsolation) {
54735508 // We found an explicitly 'nonisolated' protocol.
54745509 foundIsolation = {
@@ -6131,12 +6166,27 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
61316166 return {};
61326167
61336168 if (dc != dyn_cast<DeclContext>(value)) {
6169+ // If the nominal type is global-actor-isolated, there's nothing
6170+ // more to look for.
61346171 if (getActorIsolation (nominal).isMainActor ())
61356172 break ;
61366173
6137- return {};
6174+ // If this is an extension of a nonisolated type, its isolation
6175+ // is independent of the type.
6176+ if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
6177+ // If there were isolation attributes on the extension, respect
6178+ // them.
6179+ if (getIsolationFromAttributes (ext).has_value ())
6180+ return {};
6181+
6182+ // Keep looking.
6183+ } else {
6184+ // The type is nonisolated, so its members are nonisolated.
6185+ return {};
6186+ }
61386187 }
61396188 }
6189+
61406190 dc = dc->getParent ();
61416191 }
61426192
@@ -6166,12 +6216,8 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
61666216 return {};
61676217 };
61686218
6169- DefaultIsolation defaultIsolation = ctx.LangOpts .DefaultIsolationBehavior ;
6170- if (auto *SF = value->getDeclContext ()->getParentSourceFile ()) {
6171- if (auto defaultIsolationInFile = SF->getDefaultIsolation ())
6172- defaultIsolation = defaultIsolationInFile.value ();
6173- }
6174-
6219+ DefaultIsolation defaultIsolation =
6220+ getDefaultIsolationForContext (value->getDeclContext ());
61756221 // If we are required to use main actor... just use that.
61766222 if (defaultIsolation == DefaultIsolation::MainActor)
61776223 if (auto result =
@@ -6248,6 +6294,36 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
62486294 return {{ActorIsolation::forUnspecified (), {}}, nullptr , {}};
62496295}
62506296
6297+ // / Determines when the given "self" isolation should override default
6298+ // / isolation.
6299+ static bool shouldSelfIsolationOverrideDefault (
6300+ ASTContext &ctx, const DeclContext *dc,
6301+ const ActorIsolation &selfIsolation) {
6302+ switch (selfIsolation) {
6303+ case ActorIsolation::ActorInstance:
6304+ case ActorIsolation::Erased:
6305+ case ActorIsolation::GlobalActor:
6306+ // Actor isolation always overrides.
6307+ return true ;
6308+
6309+ case ActorIsolation::Unspecified:
6310+ // Unspecified isolation never overrides.
6311+ return false ;
6312+
6313+ case ActorIsolation::Nonisolated:
6314+ case ActorIsolation::NonisolatedUnsafe:
6315+ case ActorIsolation::CallerIsolationInheriting:
6316+ // Explicit nonisolated used to overwrite default isolation all the time,
6317+ // but under NoExplicitNonIsolated it doesn't affect extensions.
6318+ if (isa<NominalTypeDecl>(dc))
6319+ return true ;
6320+
6321+ // / Only allow explicit nonisolated to override the default when it's
6322+ // / treated as special.
6323+ return explicitNonisolatedIsSpecial (dc);
6324+ }
6325+ }
6326+
62516327static InferredActorIsolation computeActorIsolation (Evaluator &evaluator,
62526328 ValueDecl *value) {
62536329 // If this declaration has actor-isolated "self", it's isolated to that
@@ -6580,7 +6656,8 @@ static InferredActorIsolation computeActorIsolation(Evaluator &evaluator,
65806656 // has isolation, use that.
65816657 if (auto selfTypeDecl = value->getDeclContext ()->getSelfNominalTypeDecl ()) {
65826658 auto selfTypeIsolation = getInferredActorIsolation (selfTypeDecl);
6583- if (selfTypeIsolation.isolation ) {
6659+ if (shouldSelfIsolationOverrideDefault (
6660+ ctx, value->getDeclContext (), selfTypeIsolation.isolation )) {
65846661 auto isolation = selfTypeIsolation.isolation ;
65856662
65866663 if (ctx.LangOpts .hasFeature (Feature::NonisolatedNonsendingByDefault) &&
@@ -8426,6 +8503,19 @@ ActorIsolation swift::inferConformanceIsolation(
84268503 // isolated to a global actor, we may use the conforming type's isolation.
84278504 auto nominalIsolation = getActorIsolation (nominal);
84288505 if (!nominalIsolation.isGlobalActor ()) {
8506+ // If we are in an extension of the type, we might still infer an
8507+ // isolated conformance depending on default isolation and on the extension
8508+ // itself.
8509+ if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
8510+ // If there's an isolation-related attribute on the extension, use it.
8511+ if (auto attrIsolation = getIsolationFromAttributes (ext))
8512+ return *attrIsolation;
8513+
8514+ // If we're defaulting to main-actor isolation, use that.
8515+ if (getDefaultIsolationForContext (dc) == DefaultIsolation::MainActor)
8516+ return ActorIsolation::forMainActor (ctx);
8517+ }
8518+
84298519 return ActorIsolation::forNonisolated (false );
84308520 }
84318521
0 commit comments