Skip to content

Commit 7cad231

Browse files
committed
[Concurrency] Actor cannot conform to global actor isolated protocol
Attempting to conform an actor to a global actor isolated protocol creates a clash in isolation when members are accessed so, let's detect and diagnose that. Resolves: rdar://75849035 (cherry picked from commit ecfff76)
1 parent 6a117d7 commit 7cad231

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4459,6 +4459,11 @@ ERROR(global_actor_isolated_requirement_witness_conflict,none,
44594459
"%0 %1 isolated to global actor %2 can not satisfy corresponding "
44604460
"requirement from protocol %3 isolated to global actor %4",
44614461
(DescriptiveDeclKind, DeclName, Type, Identifier, Type))
4462+
ERROR(actor_cannot_conform_to_global_actor_protocol,none,
4463+
"actor %0 cannot conform to global actor isolated protocol %1",
4464+
(Type, Type))
4465+
NOTE(protocol_isolated_to_global_actor_here,none,
4466+
"%0 is isolated to global actor %1 here", (Type, Type))
44624467

44634468
WARNING(non_concurrent_param_type,none,
44644469
"cannot pass argument of non-sendable type %0 across actors",

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,26 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
18991899
return conformance;
19001900
}
19011901

1902+
if (T->isActorType()) {
1903+
if (auto globalActor = Proto->getGlobalActorAttr()) {
1904+
C.Diags.diagnose(ComplainLoc,
1905+
diag::actor_cannot_conform_to_global_actor_protocol, T,
1906+
ProtoType);
1907+
1908+
CustomAttr *attr;
1909+
NominalTypeDecl *actor;
1910+
1911+
std::tie(attr, actor) = *globalActor;
1912+
1913+
C.Diags.diagnose(attr->getLocation(),
1914+
diag::protocol_isolated_to_global_actor_here, ProtoType,
1915+
actor->getDeclaredInterfaceType());
1916+
1917+
conformance->setInvalid();
1918+
return conformance;
1919+
}
1920+
}
1921+
19021922
if (Proto->isObjC()) {
19031923
// Foreign classes cannot conform to objc protocols.
19041924
if (auto clas = canT->getClassOrBoundGenericClass()) {

test/Concurrency/actor_isolation.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,3 +818,15 @@ extension MyActor {
818818
}
819819
}
820820
}
821+
822+
@available(SwiftStdlib 5.5, *)
823+
@MainActor // expected-note {{'GloballyIsolatedProto' is isolated to global actor 'MainActor' here}}
824+
protocol GloballyIsolatedProto {
825+
}
826+
827+
// rdar://75849035 - trying to conform an actor to a global-actor isolated protocol should result in an error
828+
func test_conforming_actor_to_global_actor_protocol() {
829+
@available(SwiftStdlib 5.5, *)
830+
actor MyValue : GloballyIsolatedProto {}
831+
// expected-error@-1 {{actor 'MyValue' cannot conform to global actor isolated protocol 'GloballyIsolatedProto'}}
832+
}

test/Concurrency/actor_isolation_unsafe.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,13 @@ class C7: C2 {
100100
globalSome() // okay
101101
}
102102
}
103+
104+
@MainActor(unsafe) // expected-note {{'GloballyIsolatedProto' is isolated to global actor 'MainActor' here}}
105+
protocol GloballyIsolatedProto {
106+
}
107+
108+
// rdar://75849035 - trying to conform an actor to a global-actor isolated protocol should result in an error
109+
func test_conforming_actor_to_global_actor_protocol() {
110+
actor MyValue : GloballyIsolatedProto {}
111+
// expected-error@-1 {{actor 'MyValue' cannot conform to global actor isolated protocol 'GloballyIsolatedProto'}}
112+
}

0 commit comments

Comments
 (0)