1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
// RUN: %target-swift-frontend -typecheck -verify %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'}}
}
@globalActor
struct GA3 { // expected-error{{type 'GA3' does not conform to protocol 'GlobalActor'}}
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'}}
}
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 { } // expected-error{{deinitializer cannot have a global actor}}
}
@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 3{{instance method 'conflict1()' has multiple actor-isolation attributes ('nonisolated' and 'GA1')}}
}
// -----------------------------------------------------------------------
// 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}} {{158:7-11=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{156: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'}} {{156: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}} {{184:7-11=}}
// expected-note@-1 {{move global actor attribute to property 'test1'}} {{182: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'}} {{182: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'}} {{191: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(_:)'}} {{197:5-5=@GA1}}
}
@GA1 subscript(y: Bool) -> String {
get { "" }
@GA1 set { } // expected-warning {{setter cannot have a global actor}} {{7-12=}}
}
}
}
|