File: global_actor.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (208 lines) | stat: -rw-r--r-- 7,676 bytes parent folder | download
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=}}
    }
  }
}