Files
swift-mirror/test/attr/global_actor.swift
Henrik G. Olsson cbc0ec3b88 Add -verify-ignore-unrelated where necessary (NFC)
These are tests that fail in the next commit without this flag. This
does not add -verify-ignore-unrelated to all tests with -verify, only
the ones that would fail without it. This is NFC since this flag is
currently a no-op.
2025-10-04 14:19:52 -07:00

209 lines
7.6 KiB
Swift

// RUN: %target-swift-frontend -typecheck -verify -verify-ignore-unrelated %s -disable-availability-checking -package-name myPkg
// REQUIRES: concurrency
actor SomeActor { }
// -----------------------------------------------------------------------
// @globalActor attribute itself.
// -----------------------------------------------------------------------
// Well-formed global actor.
@globalActor
struct GA1 {
static let shared = SomeActor()
}
@globalActor
struct GenericGlobalActor<T> {
static var shared: SomeActor { SomeActor() }
}
// Ill-formed global actors.
@globalActor
final class GA2 { // expected-error{{type 'GA2' does not conform to protocol 'GlobalActor'}} expected-note {{add stubs for conformance}}
}
@globalActor
struct GA3 { // expected-error{{type 'GA3' does not conform to protocol 'GlobalActor'}} expected-note {{add stubs for conformance}}
let shared = SomeActor()
}
@globalActor
struct GA4 {
private static let shared = SomeActor() // expected-error{{property 'shared' must be as accessible as its enclosing type because it matches a requirement in protocol 'GlobalActor'}}
// expected-note@-1{{mark the static property as 'internal' to satisfy the requirement}}
}
@globalActor
open class GA5 { // expected-error{{non-final class 'GA5' cannot be a global actor}}
static let shared = SomeActor() // expected-error{{property 'shared' must be declared public because it matches a requirement in public protocol 'GlobalActor'}}
// expected-note@-1{{mark the static property as 'public' to satisfy the requirement}}
}
@globalActor
struct GA6<T> { // expected-error{{type 'GA6<T>' does not conform to protocol 'GlobalActor'}} expected-note {{add stubs for conformance}}
}
extension GA6 where T: Equatable {
static var shared: SomeActor { SomeActor() }
}
@globalActor
final class GA7 { // expected-error{{type 'GA7' does not conform to protocol 'GlobalActor'}}
static let shared = 5 // expected-note{{candidate would match and infer 'ActorType' = 'Int' if 'Int' conformed to 'Actor'}}
}
// -----------------------------------------------------------------------
// Applying global actors to entities.
// -----------------------------------------------------------------------
@globalActor
struct OtherGlobalActor {
static let shared = SomeActor()
}
@GA1 func f() {
@GA1 let x = 17 // expected-error{{local variable 'x' cannot have a global actor}}
_ = x
}
@GA1 struct X {
@GA1 var member: Int
}
struct Y {
@GA1 subscript(i: Int) -> Int { i }
}
@GA1 extension Y { }
@GA1 func g() { }
class SomeClass {
@GA1 init() { }
@GA1 deinit { }
}
@GA1 typealias Integer = Int // expected-error{{type alias cannot have a global actor}}
@GA1 actor ActorInTooManyPlaces { } // expected-error{{actor 'ActorInTooManyPlaces' cannot have a global actor}}
@GA1 @OtherGlobalActor func twoGlobalActors() { } // expected-error{{declaration can not have multiple global actor attributes ('OtherGlobalActor' and 'GA1')}}
struct Container {
// FIXME: Diagnostic could be improved to show the generic arguments.
@GenericGlobalActor<Int> @GenericGlobalActor<String> func twoGenericGlobalActors() { } // expected-error{{declaration can not have multiple global actor attributes ('GenericGlobalActor' and 'GenericGlobalActor')}}
}
// -----------------------------------------------------------------------
// Redundant attributes
// -----------------------------------------------------------------------
extension SomeActor {
@GA1 nonisolated func conflict1() { } // expected-error {{instance method 'conflict1()' has multiple actor-isolation attributes (@GA1 and 'nonisolated')}}
}
// -----------------------------------------------------------------------
// Access
// -----------------------------------------------------------------------
@globalActor
private struct PrivateGA { // expected-note 3 {{type declared here}}
actor Actor {}
static let shared = Actor()
}
@globalActor
internal struct InternalGA { // expected-note 2 {{type declared here}}
actor Actor {}
static let shared = Actor()
}
@globalActor
package struct PackageGA { // expected-note 1 {{type declared here}}
package actor Actor {}
package static let shared = Actor()
}
@globalActor
public struct PublicGA {
public actor Actor {}
public static let shared = Actor()
}
@PrivateGA private struct PrivateStructPrivateGA {}
@InternalGA private struct PrivateStructInternalGA {}
@PackageGA private struct PrivateStructPackageGA {}
@PublicGA private struct PrivateStructPublicGA {}
@PrivateGA internal struct InternalStructPrivateGA {} // expected-error {{internal struct 'InternalStructPrivateGA' cannot have private global actor 'PrivateGA'}}
@InternalGA internal struct InternalStructInternalGA {}
@PackageGA internal struct InternalStructPackageGA {}
@PublicGA internal struct InternalStructPublicGA {}
@PrivateGA package class PackageClassPrivateGA {} // expected-error {{package class 'PackageClassPrivateGA' cannot have private global actor 'PrivateGA'}}
@InternalGA package class PackageClassInternalGA {} // expected-error {{package class 'PackageClassInternalGA' cannot have internal global actor 'InternalGA'}}
@PackageGA package struct PackageClassPackageGA {}
@PublicGA package class PackageClassPublicGA {}
@PrivateGA open class OpenClassPrivateGA {} // expected-error {{open class 'OpenClassPrivateGA' cannot have private global actor 'PrivateGA'}}
@InternalGA open class OpenClassInternalGA {} // expected-error {{open class 'OpenClassInternalGA' cannot have internal global actor 'InternalGA'}}
@PackageGA open class OpenClassPackageGA {} // expected-error {{open class 'OpenClassPackageGA' cannot have package global actor 'PackageGA'}}
@PublicGA open class OpenClassPublicGA {}
// rdar://99281333 - no accessors/addressors/observers expect to 'get' are allowed to have a global actor attribute
do {
class TestInvalidAccessors {
var test1: Int {
get { 42 }
@GA1
set { } // expected-warning {{setter cannot have a global actor}} {{-1:7-11=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{-3:5-5=@GA1}}
@GA1 _modify { fatalError() } // expected-warning {{_modify accessor cannot have a global actor}} {{7-12=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{-6:5-5=@GA1}}
}
func local() {
var test: Bool {
get { false }
@GA1
set { } // expected-warning {{setter cannot have a global actor}}
}
}
@GA1 var testAlreadyWithGlobal: String {
get { "" }
@GA1 set { } // expected-warning {{setter cannot have a global actor}} {{7-12=}}
}
}
struct TestStruct {
var test1: Int {
get { 42 }
@GA1
set { } // expected-warning {{setter cannot have a global actor}} {{-1:7-11=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{-3:5-5=@GA1}}
@GA1 _modify { fatalError() } // expected-warning {{_modify accessor cannot have a global actor}} {{7-12=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{-5:5-5=@GA1}}
}
var test2: Int {
@GA1 willSet { // expected-warning {{willSet observer cannot have a global actor}} {{7-12=}}
// expected-note@-1 {{move global actor attribute to property 'test2'}} {{-1:5-5=@GA1}}
}
}
subscript(x: Int) -> Bool {
get { true }
@GA1 set { } // expected-warning {{setter cannot have a global actor}} {{7-12=}}
// expected-note@-1 {{move global actor attribute to subscript 'subscript(_:)'}} {{-2:5-5=@GA1}}
}
@GA1 subscript(y: Bool) -> String {
get { "" }
@GA1 set { } // expected-warning {{setter cannot have a global actor}} {{7-12=}}
}
}
}