@@ -4688,6 +4688,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
46884688 auto isolatedAttr = decl->getAttrs ().getAttribute <IsolatedAttr>();
46894689 auto nonisolatedAttr = decl->getAttrs ().getAttribute <NonisolatedAttr>();
46904690 auto globalActorAttr = decl->getGlobalActorAttr ();
4691+ auto concurrentExecutionAttr = decl->getAttrs ().getAttribute <ExecutionAttr>();
46914692
46924693 // Remove implicit attributes if we only care about explicit ones.
46934694 if (onlyExplicit) {
@@ -4697,61 +4698,34 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
46974698 isolatedAttr = nullptr ;
46984699 if (globalActorAttr && globalActorAttr->first ->isImplicit ())
46994700 globalActorAttr = std::nullopt ;
4701+ if (concurrentExecutionAttr && concurrentExecutionAttr->isImplicit ())
4702+ concurrentExecutionAttr = nullptr ;
47004703 }
47014704
4702- unsigned numIsolationAttrs = (isolatedAttr ? 1 : 0 ) +
4703- (nonisolatedAttr ? 1 : 0 ) +
4704- (globalActorAttr ? 1 : 0 );
4705+ unsigned numIsolationAttrs =
4706+ (isolatedAttr ? 1 : 0 ) + (nonisolatedAttr ? 1 : 0 ) +
4707+ (globalActorAttr ? 1 : 0 ) + (concurrentExecutionAttr ? 1 : 0 );
47054708 if (numIsolationAttrs == 0 ) {
47064709 if (isa<DestructorDecl>(decl) && !decl->isImplicit ()) {
47074710 return ActorIsolation::forNonisolated (false );
47084711 }
47094712 return std::nullopt ;
47104713 }
47114714
4712- // Only one such attribute is valid, but we only actually care of one of
4713- // them is a global actor.
4714- if (numIsolationAttrs > 1 && globalActorAttr && shouldDiagnose) {
4715- struct NameAndRange {
4716- StringRef name;
4717- SourceRange range;
4718-
4719- NameAndRange (StringRef _name, SourceRange _range)
4720- : name(_name), range(_range) {}
4721- };
4722-
4723- llvm::SmallVector<NameAndRange, 3 > attributes;
4724- if (isolatedAttr) {
4725- attributes.push_back (NameAndRange (isolatedAttr->getAttrName (),
4726- isolatedAttr->getRangeWithAt ()));
4727- }
4728- if (nonisolatedAttr) {
4729- attributes.push_back (NameAndRange (nonisolatedAttr->getAttrName (),
4730- nonisolatedAttr->getRangeWithAt ()));
4731- }
4732- if (globalActorAttr) {
4733- attributes.push_back (
4734- NameAndRange (globalActorAttr->second ->getName ().str (),
4735- globalActorAttr->first ->getRangeWithAt ()));
4736- }
4737- if (attributes.size () == 3 ) {
4738- decl->diagnose (diag::actor_isolation_multiple_attr_3, decl,
4739- attributes[0 ].name , attributes[1 ].name , attributes[2 ].name )
4740- .highlight (attributes[0 ].range )
4741- .highlight (attributes[1 ].range )
4742- .highlight (attributes[2 ].range );
4743- } else {
4744- assert (attributes.size () == 2 );
4745- decl->diagnose (diag::actor_isolation_multiple_attr_2, decl,
4746- attributes[0 ].name , attributes[1 ].name )
4747- .highlight (attributes[0 ].range )
4748- .highlight (attributes[1 ].range );
4749- }
4750- }
4751-
47524715 // If the declaration is explicitly marked 'nonisolated', report it as
47534716 // independent.
47544717 if (nonisolatedAttr) {
4718+ // If the nonisolated async inherits isolation from context is set, return
4719+ // caller isolation inheriting.
4720+ if (decl->getASTContext ().LangOpts .hasFeature (
4721+ Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
4722+ if (auto *func = dyn_cast<AbstractFunctionDecl>(decl);
4723+ func && func->hasAsync () &&
4724+ func->getModuleContext () == decl->getASTContext ().MainModule ) {
4725+ return ActorIsolation::forCallerIsolationInheriting ();
4726+ }
4727+ }
4728+
47554729 return ActorIsolation::forNonisolated (nonisolatedAttr->isUnsafe ());
47564730 }
47574731
@@ -4842,6 +4816,17 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
48424816 .withPreconcurrency (decl->preconcurrency () || isUnsafe);
48434817 }
48444818
4819+ // If the declaration is explicitly marked with 'execution', return the
4820+ // appropriate isolation.
4821+ if (concurrentExecutionAttr) {
4822+ switch (concurrentExecutionAttr->getBehavior ()) {
4823+ case ExecutionKind::Concurrent:
4824+ return ActorIsolation::forNonisolated (false /* is unsafe*/ );
4825+ case ExecutionKind::Caller:
4826+ return ActorIsolation::forCallerIsolationInheriting ();
4827+ }
4828+ }
4829+
48454830 llvm_unreachable (" Forgot about an attribute?" );
48464831}
48474832
@@ -5614,15 +5599,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
56145599 checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
56155600 }
56165601
5617- if (ctx.LangOpts .hasFeature (
5618- Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5619- if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5620- func && func->hasAsync () && isolationFromAttr->isNonisolated () &&
5621- func->getModuleContext () == ctx.MainModule ) {
5622- return {ActorIsolation::forCallerIsolationInheriting (), {}};
5623- }
5624- }
5625-
56265602 return {*isolationFromAttr,
56275603 IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
56285604 }
0 commit comments