@@ -4753,6 +4753,24 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
47534753 return std::nullopt ;
47544754 }
47554755
4756+ // If the declaration is explicitly marked with 'execution', return the
4757+ // appropriate isolation.
4758+ //
4759+ // NOTE: This needs to occur before we handle an explicit nonisolated attr,
4760+ // since if @execution and nonisolated are used together, we want to ensure
4761+ // that @execution takes priority. This ensures that if we import code from a
4762+ // module that was compiled with a different value for
4763+ // NonIsolatedAsyncInheritsIsolationFromContext, we get the semantics of the
4764+ // source module.
4765+ if (concurrentExecutionAttr) {
4766+ switch (concurrentExecutionAttr->getBehavior ()) {
4767+ case ExecutionKind::Concurrent:
4768+ return ActorIsolation::forNonisolated (false /* is unsafe*/ );
4769+ case ExecutionKind::Caller:
4770+ return ActorIsolation::forCallerIsolationInheriting ();
4771+ }
4772+ }
4773+
47564774 // If the declaration is explicitly marked 'nonisolated', report it as
47574775 // independent.
47584776 if (nonisolatedAttr) {
@@ -4857,17 +4875,6 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
48574875 .withPreconcurrency (decl->preconcurrency () || isUnsafe);
48584876 }
48594877
4860- // If the declaration is explicitly marked with 'execution', return the
4861- // appropriate isolation.
4862- if (concurrentExecutionAttr) {
4863- switch (concurrentExecutionAttr->getBehavior ()) {
4864- case ExecutionKind::Concurrent:
4865- return ActorIsolation::forNonisolated (false /* is unsafe*/ );
4866- case ExecutionKind::Caller:
4867- return ActorIsolation::forCallerIsolationInheriting ();
4868- }
4869- }
4870-
48714878 llvm_unreachable (" Forgot about an attribute?" );
48724879}
48734880
@@ -5534,6 +5541,9 @@ static void addAttributesForActorIsolation(ValueDecl *value,
55345541 ASTContext &ctx = value->getASTContext ();
55355542 switch (isolation) {
55365543 case ActorIsolation::CallerIsolationInheriting:
5544+ value->getAttrs ().add (new (ctx) ExecutionAttr (ExecutionKind::Caller,
5545+ /* implicit=*/ true ));
5546+ break ;
55375547 case ActorIsolation::Nonisolated:
55385548 case ActorIsolation::NonisolatedUnsafe: {
55395549 value->getAttrs ().add (new (ctx) NonisolatedAttr (
@@ -5568,6 +5578,83 @@ static void addAttributesForActorIsolation(ValueDecl *value,
55685578 }
55695579}
55705580
5581+ // / Determine the default isolation and isolation source for this declaration,
5582+ // / which may still be overridden by other inference rules.
5583+ static std::tuple<InferredActorIsolation, ValueDecl *,
5584+ std::optional<ActorIsolation>>
5585+ computeDefaultInferredActorIsolation (ValueDecl *value) {
5586+ auto &ctx = value->getASTContext ();
5587+
5588+ // If we are supposed to infer main actor isolation by default for entities
5589+ // within our module, make our default isolation main actor.
5590+ if (ctx.LangOpts .hasFeature (Feature::UnspecifiedMeansMainActorIsolated) &&
5591+ value->getModuleContext () == ctx.MainModule ) {
5592+
5593+ // Default global actor isolation does not apply to any declarations
5594+ // within actors and distributed actors.
5595+ bool inActorContext = false ;
5596+ auto *dc = value->getInnermostDeclContext ();
5597+ while (dc && !inActorContext) {
5598+ if (auto *nominal = dc->getSelfNominalTypeDecl ()) {
5599+ inActorContext = nominal->isAnyActor ();
5600+ }
5601+ dc = dc->getParent ();
5602+ }
5603+
5604+ if (!inActorContext) {
5605+ // FIXME: deinit should be implicitly MainActor too.
5606+ if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5607+ isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5608+ isa<ConstructorDecl>(value)) {
5609+ return {{ActorIsolation::forMainActor (ctx), {}}, nullptr , {}};
5610+ }
5611+ }
5612+ }
5613+
5614+ // If we have an async function... by default we inherit isolation.
5615+ if (ctx.LangOpts .hasFeature (
5616+ Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5617+ if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5618+ func && func->hasAsync () &&
5619+ func->getModuleContext () == ctx.MainModule ) {
5620+ return {
5621+ {ActorIsolation::forCallerIsolationInheriting (), {}}, nullptr , {}};
5622+ }
5623+ }
5624+
5625+ if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
5626+ // A @Sendable function is assumed to be actor-independent.
5627+ if (func->isSendable ()) {
5628+ return {
5629+ {ActorIsolation::forNonisolated (/* unsafe=*/ false ), {}}, nullptr , {}};
5630+ }
5631+ }
5632+
5633+ // When no other isolation applies, an actor's non-async init is independent
5634+ if (auto nominal = value->getDeclContext ()->getSelfNominalTypeDecl ())
5635+ if (nominal->isAnyActor ())
5636+ if (auto ctor = dyn_cast<ConstructorDecl>(value))
5637+ if (!ctor->hasAsync ())
5638+ return {{ActorIsolation::forNonisolated (/* unsafe=*/ false ), {}},
5639+ nullptr ,
5640+ {}};
5641+
5642+ // Look for and remember the overridden declaration's isolation.
5643+ if (auto *overriddenValue = value->getOverriddenDeclOrSuperDeinit ()) {
5644+ // Use the overridden decl's isolation as the default isolation for this
5645+ // decl.
5646+ auto isolation = getOverriddenIsolationFor (value);
5647+ return {{isolation,
5648+ IsolationSource (overriddenValue, IsolationSource::Override)},
5649+ overriddenValue,
5650+ isolation}; // use the overridden decl's iso as the default
5651+ // isolation for this decl.
5652+ }
5653+
5654+ // We did not find anything special, return unspecified.
5655+ return {{ActorIsolation::forUnspecified (), {}}, nullptr , {}};
5656+ }
5657+
55715658InferredActorIsolation ActorIsolationRequest::evaluate (
55725659 Evaluator &evaluator, ValueDecl *value) const {
55735660 // If this declaration has actor-isolated "self", it's isolated to that
@@ -5611,7 +5698,20 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
56115698 value->getAttrs ().add (preconcurrency);
56125699 }
56135700
5614- if (FuncDecl *fd = dyn_cast<FuncDecl>(value)) {
5701+ // Check if we inferred CallerIsolationInheriting from our isolation attr, but
5702+ // did not have an ExecutionKind::Caller attached to it.
5703+ //
5704+ // DISCUSSION: This occurs when we have a value decl that is explicitly marked
5705+ // as nonisolated but since NonIsolatedAsyncInheritsIsolationFromContext is
5706+ // enabled, we return CallerIsolationInheriting.
5707+ if (isolationFromAttr && isolationFromAttr->getKind () ==
5708+ ActorIsolation::CallerIsolationInheriting &&
5709+ !value->getAttrs ().hasAttribute <ExecutionAttr>()) {
5710+ value->getAttrs ().add (new (ctx) ExecutionAttr (ExecutionKind::Caller,
5711+ /* implicit=*/ true ));
5712+ }
5713+
5714+ if (auto *fd = dyn_cast<FuncDecl>(value)) {
56155715 // Main.main() and Main.$main are implicitly MainActor-protected.
56165716 // Any other isolation is an error.
56175717 std::optional<ActorIsolation> mainIsolation =
@@ -5644,74 +5744,11 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
56445744 IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
56455745 }
56465746
5647- // Determine the default isolation for this declaration, which may still be
5648- // overridden by other inference rules.
5649- ActorIsolation defaultIsolation = ActorIsolation::forUnspecified ();
5650- IsolationSource defaultIsolationSource;
5651-
5652- // If we are supposed to infer main actor isolation by default for entities
5653- // within our module, make our default isolation main actor.
5654- if (ctx.LangOpts .hasFeature (Feature::UnspecifiedMeansMainActorIsolated) &&
5655- value->getModuleContext () == ctx.MainModule ) {
5656-
5657- // Default global actor isolation does not apply to any declarations
5658- // within actors and distributed actors.
5659- bool inActorContext = false ;
5660- auto *dc = value->getInnermostDeclContext ();
5661- while (dc && !inActorContext) {
5662- if (auto *nominal = dc->getSelfNominalTypeDecl ()) {
5663- inActorContext = nominal->isAnyActor ();
5664- }
5665- dc = dc->getParent ();
5666- }
5667-
5668- if (!inActorContext) {
5669- // FIXME: deinit should be implicitly MainActor too.
5670- if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5671- isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5672- isa<ConstructorDecl>(value)) {
5673- defaultIsolation = ActorIsolation::forMainActor (ctx);
5674- }
5675- }
5676- }
5677-
5678- // If we have an async function... by default we inherit isolation.
5679- if (ctx.LangOpts .hasFeature (
5680- Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5681- if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5682- func && func->hasAsync () &&
5683- func->getModuleContext () == ctx.MainModule ) {
5684- defaultIsolation = ActorIsolation::forCallerIsolationInheriting ();
5685- }
5686- }
5687-
5688- if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
5689- // A @Sendable function is assumed to be actor-independent.
5690- if (func->isSendable ()) {
5691- defaultIsolation = ActorIsolation::forNonisolated (/* unsafe=*/ false );
5692- }
5693- }
5694-
5695- // When no other isolation applies, an actor's non-async init is independent
5696- if (auto nominal = value->getDeclContext ()->getSelfNominalTypeDecl ())
5697- if (nominal->isAnyActor ())
5698- if (auto ctor = dyn_cast<ConstructorDecl>(value))
5699- if (!ctor->hasAsync ())
5700- defaultIsolation = ActorIsolation::forNonisolated (/* unsafe=*/ false );
5701-
5702- // Look for and remember the overridden declaration's isolation.
5703- std::optional<ActorIsolation> overriddenIso;
5704- ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit ();
5705- if (overriddenValue) {
5706- // use the overridden decl's iso as the default isolation for this decl.
5707- defaultIsolation = getOverriddenIsolationFor (value);
5708- defaultIsolationSource =
5709- IsolationSource (overriddenValue, IsolationSource::Override);
5710- overriddenIso = defaultIsolation;
5711- }
5712-
5713- // NOTE: After this point, the default has been set. Only touch the default
5714- // isolation above this point since code below assumes it is now constant.
5747+ InferredActorIsolation defaultIsolation;
5748+ ValueDecl *overriddenValue;
5749+ std::optional<ActorIsolation> overridenIsolation;
5750+ std::tie (defaultIsolation, overriddenValue, overridenIsolation) =
5751+ computeDefaultInferredActorIsolation (value);
57155752
57165753 // Function used when returning an inferred isolation.
57175754 auto inferredIsolation = [&](ActorIsolation inferred,
@@ -5722,16 +5759,17 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
57225759 // if the inferred isolation is not valid, then carry-over the overridden
57235760 // declaration's isolation as this decl's inferred isolation.
57245761 switch (validOverrideIsolation (value, inferred, overriddenValue,
5725- *overriddenIso )) {
5762+ *overridenIsolation )) {
57265763 case OverrideIsolationResult::Allowed:
57275764 case OverrideIsolationResult::Sendable:
57285765 break ;
57295766
57305767 case OverrideIsolationResult::Disallowed:
5731- if (overriddenValue->hasClangNode () && overriddenIso->isUnspecified ()) {
5732- inferred = overriddenIso->withPreconcurrency (true );
5768+ if (overriddenValue->hasClangNode () &&
5769+ overridenIsolation->isUnspecified ()) {
5770+ inferred = overridenIsolation->withPreconcurrency (true );
57335771 } else {
5734- inferred = *overriddenIso ;
5772+ inferred = *overridenIsolation ;
57355773 }
57365774 break ;
57375775 }
@@ -5758,6 +5796,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
57585796 addAttributesForActorIsolation (value, inferred);
57595797 break ;
57605798 case ActorIsolation::CallerIsolationInheriting:
5799+ addAttributesForActorIsolation (value, inferred);
57615800 break ;
57625801 case ActorIsolation::Erased:
57635802 llvm_unreachable (" cannot infer erased isolation" );
@@ -5988,8 +6027,18 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
59886027 }
59896028 }
59906029
5991- // Default isolation for this member.
5992- return {defaultIsolation, defaultIsolationSource};
6030+ // We did not invoke any earlier rules... so just return the default
6031+ // isolation.
6032+ if (defaultIsolation.isolation .getKind () ==
6033+ ActorIsolation::CallerIsolationInheriting) {
6034+ // If we have caller isolation inheriting, attach the attribute for it so
6035+ // that we preserve that we chose CallerIsolationInheriting through
6036+ // serialization. We do this since we need to support compiling where
6037+ // nonisolated is the default and where caller isolation inheriting is the
6038+ // default.
6039+ addAttributesForActorIsolation (value, defaultIsolation.isolation );
6040+ }
6041+ return defaultIsolation;
59936042}
59946043
59956044bool HasIsolatedSelfRequest::evaluate (
0 commit comments