@@ -4688,6 +4688,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
4688
4688
auto isolatedAttr = decl->getAttrs ().getAttribute <IsolatedAttr>();
4689
4689
auto nonisolatedAttr = decl->getAttrs ().getAttribute <NonisolatedAttr>();
4690
4690
auto globalActorAttr = decl->getGlobalActorAttr ();
4691
+ auto concurrentExecutionAttr = decl->getAttrs ().getAttribute <ExecutionAttr>();
4691
4692
4692
4693
// Remove implicit attributes if we only care about explicit ones.
4693
4694
if (onlyExplicit) {
@@ -4697,61 +4698,34 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
4697
4698
isolatedAttr = nullptr ;
4698
4699
if (globalActorAttr && globalActorAttr->first ->isImplicit ())
4699
4700
globalActorAttr = std::nullopt ;
4701
+ if (concurrentExecutionAttr && concurrentExecutionAttr->isImplicit ())
4702
+ concurrentExecutionAttr = nullptr ;
4700
4703
}
4701
4704
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 );
4705
4708
if (numIsolationAttrs == 0 ) {
4706
4709
if (isa<DestructorDecl>(decl) && !decl->isImplicit ()) {
4707
4710
return ActorIsolation::forNonisolated (false );
4708
4711
}
4709
4712
return std::nullopt ;
4710
4713
}
4711
4714
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
-
4752
4715
// If the declaration is explicitly marked 'nonisolated', report it as
4753
4716
// independent.
4754
4717
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
+
4755
4729
return ActorIsolation::forNonisolated (nonisolatedAttr->isUnsafe ());
4756
4730
}
4757
4731
@@ -4842,6 +4816,17 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
4842
4816
.withPreconcurrency (decl->preconcurrency () || isUnsafe);
4843
4817
}
4844
4818
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
+
4845
4830
llvm_unreachable (" Forgot about an attribute?" );
4846
4831
}
4847
4832
@@ -5614,15 +5599,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5614
5599
checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
5615
5600
}
5616
5601
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
-
5626
5602
return {*isolationFromAttr,
5627
5603
IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
5628
5604
}
0 commit comments