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
}
|