Skip to content

Commit dfce2aa

Browse files
committed
[Distributed] Allow isolated any DistributedActor
This was mistakenly not allowed; the logic for hopping actors will just work, however we guarded the isolated being allowed only on "is actor" but it should have been checking for "is any actor"
1 parent b5d1ecc commit dfce2aa

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

include/swift/AST/Types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
922922
/// Determines whether this type is an actor type.
923923
bool isActorType();
924924

925+
/// Determines whether this type is an any actor type.
926+
bool isAnyActorType();
927+
925928
/// Returns true if this type is a Sendable type.
926929
bool isSendableType(DeclContext *declContext);
927930

lib/AST/Type.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,12 @@ bool TypeBase::isActorType() {
574574
return false;
575575
}
576576

577+
bool TypeBase::isAnyActorType() {
578+
if (auto actor = getAnyActor())
579+
return actor->isAnyActor();
580+
return false;
581+
}
582+
577583
bool TypeBase::isSendableType(DeclContext *ctx) {
578584
return isSendableType(ctx->getParentModule());
579585
}

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4484,12 +4484,12 @@ TypeResolver::resolveIsolatedTypeRepr(IsolatedTypeRepr *repr,
44844484
Type type = resolveType(repr->getBase(), options);
44854485

44864486
// isolated parameters must be of actor type
4487-
if (!type->hasTypeParameter() && !type->isActorType() && !type->hasError()) {
4487+
if (!type->hasTypeParameter() && !type->isAnyActorType() && !type->hasError()) {
44884488
// Optional actor types are fine - `nil` represents `nonisolated`.
44894489
auto wrapped = type->getOptionalObjectType();
44904490
auto allowOptional = getASTContext().LangOpts
44914491
.hasFeature(Feature::OptionalIsolatedParameters);
4492-
if (allowOptional && wrapped && wrapped->isActorType()) {
4492+
if (allowOptional && wrapped && wrapped->isAnyActorType()) {
44934493
return type;
44944494
}
44954495

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
3+
// RUN: %target-build-swift -module-name main -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
4+
// RUN: %target-codesign %t/a.out
5+
// RUN: %target-run %t/a.out
6+
7+
// REQUIRES: executable_test
8+
// REQUIRES: concurrency
9+
// REQUIRES: distributed
10+
11+
// rdar://76038845
12+
// UNSUPPORTED: use_os_stdlib
13+
// UNSUPPORTED: back_deployment_runtime
14+
// UNSUPPORTED: freestanding
15+
16+
// FIXME(distributed): Distributed actors currently have some issues on windows rdar://82593574
17+
// UNSUPPORTED: OS=windows-msvc
18+
19+
import StdlibUnittest
20+
import Distributed
21+
import FakeDistributedActorSystems
22+
23+
@available(SwiftStdlib 5.9, *)
24+
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
25+
26+
@available(SwiftStdlib 5.9, *)
27+
func globalFunc(isolatedTo actor: isolated any DistributedActor) async {
28+
MainActor.preconditionIsolated() // we forced the `actor` onto the main actor's executor
29+
}
30+
31+
@available(SwiftStdlib 5.9, *) // because conforming to the protocol requirement introduced in 5.9
32+
distributed actor NormalWorker {
33+
34+
nonisolated var unownedExecutor: UnownedSerialExecutor {
35+
return MainActor.sharedUnownedExecutor
36+
}
37+
38+
distributed func offerSelf() async {
39+
print("executed: \(#function)")
40+
MainActor.preconditionIsolated() // we forced the `actor` onto the main actor's executor
41+
42+
await globalFunc(isolatedTo: self)
43+
MainActor.preconditionIsolated() // we forced the `actor` onto the main actor's executor
44+
}
45+
}
46+
47+
@available(SwiftStdlib 5.1, *)
48+
@main struct Main {
49+
@available(SwiftStdlib 5.1, *)
50+
static func main() async {
51+
if #available(SwiftStdlib 5.9, *) {
52+
let tests = TestSuite("DistributedIsolatedTests")
53+
let system = DefaultDistributedActorSystem()
54+
let normalLocalWorker = NormalWorker(actorSystem: system)
55+
precondition(__isLocalActor(normalLocalWorker), "must be local")
56+
57+
tests.test("remote actor reference should have crash-on-enqueue executor") {
58+
try! await normalLocalWorker.offerSelf()
59+
}
60+
61+
await runAllTestsAsync()
62+
}
63+
}
64+
}

test/Distributed/distributed_actor_isolation.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,5 @@ extension Greeting where SerializationRequirement == Codable {
260260
}
261261

262262
func isolated_generic_ok<T: DistributedActor>(_ t: isolated T) {}
263+
264+
func isolated_existential_ok(_ t: isolated any DistributedActor) {}

0 commit comments

Comments
 (0)