File: global_actor_inference_swift6.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 (225 lines) | stat: -rw-r--r-- 6,019 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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// RUN: %empty-directory(%t)

// RUN: %target-swift-frontend -swift-version 6 -emit-module -emit-module-path %t/other_global_actor_inference.swiftmodule -module-name other_global_actor_inference -strict-concurrency=complete %S/Inputs/other_global_actor_inference.swift

// RUN: %target-swift-frontend -swift-version 6 -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify

// REQUIRES: concurrency

import other_global_actor_inference

actor SomeActor { }

@globalActor
struct SomeGlobalActor {
  static let shared = SomeActor()
}

@globalActor
struct OtherGlobalActor {
  static let shared = SomeActor()
}


// MARK: Property Wrappers

@propertyWrapper
actor WrapperActor<Wrapped: Sendable> {
  var storage: Wrapped

  init(wrappedValue: Wrapped) {
    storage = wrappedValue
  }

  nonisolated var wrappedValue: Wrapped {
    get { }
    set { }
  }

  nonisolated var projectedValue: Wrapped {
    get { }
    set { }
  }
}

@propertyWrapper
@OtherGlobalActor
struct WrapperOnActor<Wrapped: Sendable> {
  private var stored: Wrapped

  nonisolated init(wrappedValue: Wrapped) {
    stored = wrappedValue
  }

  @MainActor var wrappedValue: Wrapped { // expected-note {{property declared here}}
    get { }
    set { }
  }

  @SomeGlobalActor var projectedValue: Wrapped {
    get {  }
    set { }
  }
}

@MainActor
@propertyWrapper
public struct WrapperOnMainActor<Wrapped> {
  // Make sure inference of @MainActor on wrappedValue doesn't crash.

  // expected-note@+1 {{mutation of this property is only permitted within the actor}}
  public var wrappedValue: Wrapped // expected-note {{property declared here}}

  public var accessCount: Int

  nonisolated public init(wrappedValue: Wrapped) {
    // expected-error@+1 {{main actor-isolated property 'wrappedValue' can not be mutated from a nonisolated context}}
    self.wrappedValue = wrappedValue
  }
}

struct HasMainActorWrappedProp {
  @WrapperOnMainActor var thing: Int = 1 // expected-note {{property declared here}}

  var plainStorage: Int

  var computedProp: Int { 0 }

  nonisolated func testErrors() {
    _ = thing // expected-error {{main actor-isolated property 'thing' can not be referenced from a nonisolated context}}
    _ = _thing.wrappedValue // expected-error {{main actor-isolated property 'wrappedValue' can not be referenced from a nonisolated context}}

    _ = _thing
    _ = _thing.accessCount

    _ = plainStorage

    _ = computedProp
  }
}

struct HasWrapperOnActor {
  @WrapperOnActor var synced: Int = 0
  // expected-note@-1 2{{property declared here}}

  // expected-note@+1 3{{to make instance method 'testErrors()'}}
  func testErrors() {
    _ = synced // expected-error{{main actor-isolated property 'synced' can not be referenced from a nonisolated context}}
    _ = $synced // expected-error{{global actor 'SomeGlobalActor'-isolated property '$synced' can not be referenced from a nonisolated context}}
    _ = _synced
    _ = _synced.wrappedValue // expected-error{{main actor-isolated property 'wrappedValue' can not be referenced from a nonisolated context}}
  }

  @MainActor mutating func testOnMain() {
    _ = synced
    synced = 17
  }

  @WrapperActor var actorSynced: Int = 0 // expected-error{{'nonisolated' is not supported on properties with property wrappers}}

  func testActorSynced() {
    _ = actorSynced
    _ = $actorSynced
    _ = _actorSynced
  }
}

struct Carbon {
  @IntWrapper var atomicWeight: Int // expected-note {{property declared here}}

  nonisolated func getWeight() -> Int {
    return atomicWeight // expected-error {{main actor-isolated property 'atomicWeight' can not be referenced from a nonisolated context}}
  }
}

@MainActor
protocol InferMainActor {}

@propertyWrapper
@preconcurrency @MainActor
struct Wrapper<T> {
  var wrappedValue: T {
    fatalError()
  }

  init() {}
}

@MainActor
class C {
  nonisolated init() {}
}

struct S: InferMainActor {
  @Wrapper var value: C // okay, 'S' is isolated to 'MainActor'
}

protocol InferMainActorInherited: InferMainActor {
  func f() // expected-note{{mark the protocol requirement 'f()' 'async' to allow actor-isolated conformances}}
  func g()
}

@SomeGlobalActor
protocol InferSomeGlobalActor { }

protocol InferenceConflict: InferMainActorInherited, InferSomeGlobalActor { }

struct S2: InferMainActorInherited {
  func f() { } // okay, 'f' is MainActor isolated, as is the requirement
  @MainActor func g() { } // okay for the same reasons, but more explicitly
}

@SomeGlobalActor
struct S3: InferenceConflict {
  nonisolated func g() { }
}

extension S3 {
  func f() { }
  // expected-error@-1{{global actor 'SomeGlobalActor'-isolated instance method 'f()' cannot be used to satisfy main actor-isolated protocol requirement}}
  //expected-note@-2{{add 'nonisolated' to 'f()' to make this instance method not isolated to the actor}}
}

@MainActor
func onMain() {}

@MainActor
class MainActorSuperclass {}

protocol InferMainFromSuperclass: MainActorSuperclass {
  func f()
}

class C1: MainActorSuperclass, InferMainFromSuperclass {
  func f() {
    onMain() // okay
  }
}

protocol InferenceConflictWithSuperclass: MainActorSuperclass, InferSomeGlobalActor {
  func g()
  // expected-note@-1 {{mark the protocol requirement 'g()' 'async' to allow actor-isolated conformances}}
}


class C2: MainActorSuperclass, InferenceConflictWithSuperclass {
//expected-note@-1 {{add '@preconcurrency' to the 'InferenceConflictWithSuperclass' conformance to defer isolation checking to run time}}

  func f() {}

  func g() {}
  // expected-error@-1 {{main actor-isolated instance method 'g()' cannot be used to satisfy nonisolated protocol requirement}}
  // expected-note@-2 {{add 'nonisolated' to 'g()' to make this instance method not isolated to the actor}}
}


class ConformInExtension {}
extension ConformInExtension: InferMainActor {}

class InheritConformance: ConformInExtension {
  func f() {}
}

func testInheritedMainActorConformance() {
  InheritConformance().f() // okay; this is not main actor isolated
}