Files
swift-mirror/test/Distributed/distributed_actor_transfernonsendable.swift
Michael Gottesman fe2dc11cb9 [region-isolation] When computing isolation for isolated parameters, use getAnyActor instead of getNominalOrBoundGenericNominal().
This ensures that we can properly compute isolation for generic types that
conform to AnyActor.

I found this by playing with test cases from the previous commit. We would not
find an actor type for the actor instance isolation and would fall back along an
incorrect path.

rdar://128021548
2024-05-13 13:43:51 -07:00

85 lines
3.5 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift
// RUN: %target-swift-frontend -swift-version 6 -verify -verify-ignore-unknown -disable-availability-checking -I %t %s -emit-sil
// REQUIRES: concurrency
// REQUIRES: distributed
import Distributed
import FakeDistributedActorSystems
////////////////////////
// MARK: Declarations //
////////////////////////
@available(SwiftStdlib 5.5, *)
typealias DefaultDistributedActorSystem = FakeActorSystem
final class NonSendableKlass {}
extension NonSendableKlass : Codable {}
@MainActor func transferToMain<T>(_ t: T) async {}
/////////////////
// MARK: Tests //
/////////////////
distributed actor MyDistributedActor {
let x: NonSendableKlass
init(system: FakeActorSystem, y: NonSendableKlass) {
x = NonSendableKlass()
actorSystem = system
_ = { @MainActor in
// TODO: This should error saying 'y' is actor isolated.
print(y) // expected-error {{sending 'y' risks causing data races}}
// expected-note @-1 {{task-isolated 'y' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
}
}
init(system: FakeActorSystem, y2: NonSendableKlass) {
x = y2
actorSystem = system
_ = { @MainActor in
print(y2) // expected-error {{sending 'y2' risks causing data races}}
// expected-note @-1 {{'self'-isolated 'y2' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
}
}
distributed func transferActorField() async {
await transferToMain(x) // expected-error {{sending 'self.x' risks causing data races}}
// expected-note @-1 {{sending 'self'-isolated 'self.x' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and 'self'-isolated uses}}
}
distributed func transferActorIsolatedArg(_ x: NonSendableKlass) async {
await transferToMain(x) // expected-error {{sending 'x' risks causing data races}}
// expected-note @-1 {{sending 'self'-isolated 'x' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and 'self'-isolated uses}}
}
distributed func transferActorIsolatedArgIntoClosure(_ x: NonSendableKlass) async {
_ = { @MainActor in
// TODO: In 2nd part of message should say actor-isolated instead of later
// nonisolated uses in the case of a closure.
print(x) // expected-error {{sending 'x' risks causing data races}}
// expected-note @-1 {{'self'-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
}
}
}
/////////////////////////////////
// MARK: Associated Type Tests //
/////////////////////////////////
protocol AssociatedTypeTestProtocol {
associatedtype A: DistributedActor
}
func associatedTypeTestBasic<T: AssociatedTypeTestProtocol>(_: T, _: isolated T.A) {
}
func associatedTypeTestBasic2<T: AssociatedTypeTestProtocol>(_: T, iso: isolated T.A, x: NonSendableKlass) async {
await transferToMain(x) // expected-error {{sending 'x' risks causing data races}}
// expected-note @-1 {{sending 'iso'-isolated 'x' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and 'iso'-isolated uses}}
}