mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
847 lines
27 KiB
Swift
847 lines
27 KiB
Swift
// RUN: %target-swift-frontend -strict-concurrency=complete -swift-version 5 -parse-as-library -emit-sil -verify %s
|
|
|
|
|
|
func randomBool() -> Bool { return false }
|
|
func logTransaction(_ i: Int) {}
|
|
|
|
enum Color: Error {
|
|
case red
|
|
case yellow
|
|
case blue
|
|
}
|
|
|
|
func takeNonSendable(_ ns: NonSendableType) {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
func takeSendable(_ s: SendableType) {}
|
|
|
|
class NonSendableType { // expected-note *{{class 'NonSendableType' does not conform to the 'Sendable' protocol}}
|
|
var x: Int = 0
|
|
func f() {}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
struct SendableType: Sendable {}
|
|
|
|
struct Money {
|
|
var dollars: Int
|
|
var euros: Int {
|
|
return dollars * 2
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
func takeBob(_ b: Bob) {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor Bob {
|
|
var x: Int
|
|
|
|
nonisolated func speak() { }
|
|
nonisolated var cherry : String {
|
|
get { "black cherry" }
|
|
}
|
|
|
|
init(v0 initial: Int) {
|
|
self.x = 0
|
|
speak() // expected-note {{after calling instance method 'speak()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
speak()
|
|
self.x = 1 // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
speak()
|
|
}
|
|
|
|
init(v1 _: Void) {
|
|
self.x = 0
|
|
_ = cherry // expected-note {{after accessing property 'cherry', only nonisolated properties of 'self' can be accessed from this init}}
|
|
self.x = 1 // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
init(v2 callBack: (Bob) -> Void) {
|
|
self.x = 0
|
|
callBack(self) // expected-note {{after a call involving 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
self.x = 1 // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
init(v3 _: Void) {
|
|
self.x = 1
|
|
takeBob(self) // expected-note {{after calling global function 'takeBob', only nonisolated properties of 'self' can be accessed from this init}}
|
|
self.x = 1 // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
|
|
|
|
// ensure noniso does not flow out of a defer's unreachable block
|
|
init(spice doesNotFlow: Int) {
|
|
if true {
|
|
defer {
|
|
if randomBool() {
|
|
speak()
|
|
fatalError("oops")
|
|
}
|
|
}
|
|
self.x = 0
|
|
}
|
|
self.x = 20
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor Casey {
|
|
var money: Money
|
|
|
|
nonisolated func speak(_ msg: String) { print("Casey: \(msg)") }
|
|
nonisolated func cashUnderMattress() -> Int { return 0 }
|
|
|
|
init() {
|
|
money = Money(dollars: 100)
|
|
defer { logTransaction(money.euros) } // expected-warning {{cannot access property 'money' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
self.speak("Yay, I have $\(money.dollars)!") // expected-note {{after calling instance method 'speak', only nonisolated properties of 'self' can be accessed from this init}}
|
|
}
|
|
|
|
init(with start: Int) {
|
|
money = Money(dollars: start)
|
|
|
|
if (money.dollars < 0) {
|
|
self.speak("Oh no, I'm in debt!") // expected-note 3 {{after calling instance method 'speak', only nonisolated properties of 'self' can be accessed from this init}}
|
|
}
|
|
logTransaction(money.euros) // expected-warning {{cannot access property 'money' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
|
|
// expected-warning@+1 2 {{cannot access property 'money' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
money.dollars = money.dollars + 1
|
|
|
|
if randomBool() {
|
|
// expected-note@+2 {{after calling instance method 'cashUnderMattress()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
// expected-warning@+1 {{cannot access property 'money' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
money.dollars += cashUnderMattress()
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor Demons {
|
|
let ns: NonSendableType
|
|
|
|
init(_ x: NonSendableType) {
|
|
self.ns = x
|
|
}
|
|
|
|
deinit {
|
|
let _ = self.ns // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
func pass<T>(_ t: T) {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor ExampleFromProposal {
|
|
let immutableSendable = SendableType()
|
|
var mutableSendable = SendableType()
|
|
let nonSendable = NonSendableType()
|
|
nonisolated(unsafe) let unsafeNonSendable = NonSendableType()
|
|
var nsItems: [NonSendableType] = []
|
|
var sItems: [SendableType] = []
|
|
|
|
init() {
|
|
_ = self.immutableSendable // ok
|
|
_ = self.mutableSendable // ok
|
|
_ = self.nonSendable // ok
|
|
_ = self.unsafeNonSendable
|
|
|
|
f() // expected-note 2 {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
_ = self.immutableSendable // ok
|
|
_ = self.mutableSendable // expected-warning {{cannot access property 'mutableSendable' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
_ = self.nonSendable // expected-warning {{cannot access property 'nonSendable' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
_ = self.unsafeNonSendable // ok
|
|
}
|
|
|
|
|
|
deinit {
|
|
_ = self.immutableSendable // ok
|
|
_ = self.mutableSendable // ok
|
|
_ = self.nonSendable // expected-warning {{cannot access property 'nonSendable' with a non-Sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
|
|
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from a deinit}}
|
|
|
|
_ = self.immutableSendable // ok
|
|
_ = self.mutableSendable // expected-warning {{cannot access property 'mutableSendable' here in deinitializer; this is an error in the Swift 6 language mode}}
|
|
_ = self.nonSendable // expected-warning {{cannot access property 'nonSendable' with a non-Sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
nonisolated func f() {}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
@MainActor
|
|
class CheckGAIT1 {
|
|
var silly = 10
|
|
var ns = NonSendableType()
|
|
|
|
nonisolated func f() {}
|
|
|
|
nonisolated init(_ c: Color) {
|
|
silly += 0
|
|
repeat {
|
|
switch c {
|
|
case .red:
|
|
continue
|
|
case .yellow:
|
|
silly += 1
|
|
continue
|
|
case .blue:
|
|
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
}
|
|
break
|
|
} while true
|
|
silly += 2 // expected-warning {{cannot access property 'silly' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
deinit {
|
|
_ = ns // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from a deinit}}
|
|
_ = silly // expected-warning {{cannot access property 'silly' here in deinitializer; this is an error in the Swift 6 language mode}}
|
|
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor ControlFlowTester {
|
|
let ns: NonSendableType = NonSendableType()
|
|
let s: SendableType = SendableType()
|
|
var count: Int = 0
|
|
|
|
nonisolated func noniso() {}
|
|
|
|
init(v1: Void) {
|
|
noniso() // expected-note {{after calling instance method 'noniso()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
takeNonSendable(self.ns) // expected-warning {{cannot access property 'ns' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
takeSendable(self.s)
|
|
}
|
|
|
|
init(v2 c: Color) throws {
|
|
if c == .red {
|
|
noniso()
|
|
throw c
|
|
} else if c == .blue {
|
|
noniso()
|
|
fatalError("soul")
|
|
}
|
|
count += 1
|
|
}
|
|
|
|
init(v3 c: Color) {
|
|
do {
|
|
defer { noniso() } // expected-note 3 {{after calling instance method 'noniso()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
switch c {
|
|
case .red:
|
|
throw Color.red
|
|
case .blue:
|
|
throw Color.blue
|
|
case .yellow:
|
|
count = 0
|
|
throw Color.yellow
|
|
}
|
|
} catch Color.blue {
|
|
count += 1 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
} catch {
|
|
count += 1 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
count = 42 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
|
|
init(v4 c: Color) {
|
|
defer { count += 1 } // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
noniso() // expected-note 1 {{after calling instance method 'noniso()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
}
|
|
|
|
init?(v5 c: Color) throws {
|
|
if c != .red {
|
|
noniso()
|
|
return nil
|
|
}
|
|
count += 1
|
|
noniso() // expected-note {{after calling instance method 'noniso()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
if c == .blue {
|
|
throw c
|
|
}
|
|
count += 1 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
init(v5 c: Color?) {
|
|
if let c = c {
|
|
switch c {
|
|
case .red:
|
|
defer { noniso() } // expected-note 5 {{after calling instance method 'noniso()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
count = 0 // OK
|
|
fallthrough
|
|
case .blue:
|
|
count = 1 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
fallthrough
|
|
case .yellow:
|
|
count = 2 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
break
|
|
}
|
|
}
|
|
switch c {
|
|
case .some(.red):
|
|
count += 1 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
case .some(.blue):
|
|
count += 2 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
case .some(.yellow):
|
|
count += 3 // expected-warning {{cannot access property 'count' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
case .none:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
enum BogusError: Error {
|
|
case blah
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor Convenient {
|
|
var x: Int
|
|
var y: Convenient?
|
|
|
|
init(val: Int) {
|
|
self.x = val
|
|
}
|
|
|
|
init(bigVal: Int) {
|
|
if bigVal < 0 {
|
|
self.init(val: 0)
|
|
say(msg: "hello from actor!")
|
|
}
|
|
say(msg: "said this too early!") // expected-error {{'self' used before 'self.init' call or assignment to 'self'}}
|
|
self.init(val: bigVal)
|
|
|
|
Task { await self.mutateIsolatedState() }
|
|
}
|
|
|
|
init!(biggerVal1 biggerVal: Int) {
|
|
guard biggerVal < 1234567 else { return nil }
|
|
self.init(bigVal: biggerVal)
|
|
say(msg: "hello?")
|
|
}
|
|
|
|
@MainActor
|
|
init?(biggerVal2 biggerVal: Int) async {
|
|
guard biggerVal < 1234567 else { return nil }
|
|
self.init(bigVal: biggerVal)
|
|
say(msg: "hello?")
|
|
await mutateIsolatedState()
|
|
}
|
|
|
|
init() async {
|
|
self.init(val: 10)
|
|
self.x += 1
|
|
mutateIsolatedState()
|
|
}
|
|
|
|
init(throwyDesignated val: Int) throws {
|
|
guard val > 0 else { throw BogusError.blah }
|
|
self.x = 10
|
|
say(msg: "hello?")
|
|
|
|
Task { self }
|
|
}
|
|
|
|
init(asyncThrowyDesignated val: Int) async throws {
|
|
guard val > 0 else { throw BogusError.blah }
|
|
self.x = 10
|
|
say(msg: "hello?")
|
|
Task { self }
|
|
}
|
|
|
|
init(throwyConvenient val: Int) throws {
|
|
try self.init(throwyDesignated: val)
|
|
say(msg: "hello?")
|
|
Task { self }
|
|
}
|
|
|
|
func mutateIsolatedState() {
|
|
self.y = self
|
|
}
|
|
|
|
nonisolated func say(msg: String) {
|
|
print(msg)
|
|
}
|
|
}
|
|
|
|
func randomInt() -> Int { return 4 }
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
func callMethod(_ a: MyActor) {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
func passInout<T>(_ a: inout T) {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor MyActor {
|
|
var x: Int
|
|
var y: Int
|
|
var hax: MyActor?
|
|
|
|
var computedProp : Int {
|
|
get { 0 }
|
|
set { }
|
|
}
|
|
|
|
func helloWorld() {}
|
|
|
|
init(ci1 c: Bool) {
|
|
self.init(i1: c)
|
|
Task { self }
|
|
callMethod(self)
|
|
}
|
|
|
|
init(ci2 c: Bool) async {
|
|
self.init(i1: c)
|
|
self.x = 1
|
|
callMethod(self)
|
|
self.x = 0
|
|
}
|
|
|
|
init(i1 c: Bool) {
|
|
self.x = 0
|
|
_ = self.x
|
|
self.y = self.x
|
|
|
|
Task { self } // expected-note 2 {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
self.x = randomInt() // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
|
|
callMethod(self) // expected-note 5 {{after calling global function 'callMethod', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
passInout(&self.x) // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
|
|
if c {
|
|
// expected-warning@+2 {{cannot access property 'y' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
// expected-warning@+1 {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
self.x = self.y
|
|
}
|
|
|
|
// expected-warning@+2 {{cannot access property 'y' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
// expected-warning@+1 {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
(_, _) = (self.x, self.y)
|
|
_ = self.x == 0 // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
|
|
while c {
|
|
// expected-warning@+2 {{cannot access property 'hax' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
// expected-note@+1 2 {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
self.hax = self
|
|
_ = self.hax // expected-warning {{cannot access property 'hax' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
Task {
|
|
_ = await self.hax
|
|
await self.helloWorld()
|
|
}
|
|
|
|
{ _ = self }()
|
|
}
|
|
|
|
@MainActor
|
|
init(i2 c: Bool) {
|
|
self.x = 0
|
|
self.y = self.x
|
|
|
|
Task { self } // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
callMethod(self)
|
|
|
|
passInout(&self.x) // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
init(i3 c: Bool) async {
|
|
self.x = 0
|
|
self.y = self.x
|
|
|
|
Task { self }
|
|
|
|
self.helloWorld()
|
|
callMethod(self)
|
|
passInout(&self.x)
|
|
|
|
self.x = self.y
|
|
|
|
self.hax = self
|
|
_ = Optional.some(self)
|
|
|
|
_ = computedProp
|
|
computedProp = 1
|
|
|
|
Task {
|
|
_ = self.hax
|
|
self.helloWorld()
|
|
}
|
|
|
|
{ _ = self }()
|
|
}
|
|
|
|
@MainActor
|
|
init(i4 c: Bool) async {
|
|
self.x = 0
|
|
self.y = self.x
|
|
|
|
Task { self } // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
callMethod(self)
|
|
|
|
passInout(&self.x) // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor X {
|
|
var counter: Int
|
|
|
|
init(v1 start: Int) {
|
|
self.counter = start
|
|
Task { await self.setCounter(start + 1) } // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
if self.counter != start { // expected-warning {{cannot access property 'counter' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
fatalError("where's my protection?")
|
|
}
|
|
}
|
|
|
|
func setCounter(_ x : Int) {
|
|
self.counter = x
|
|
}
|
|
}
|
|
|
|
struct CardboardBox<T> {
|
|
public let item: T
|
|
}
|
|
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
var globalVar: EscapeArtist? // expected-warning {{var 'globalVar' is not concurrency-safe because it is nonisolated global shared mutable state; this is an error in the Swift 6 language mode}}
|
|
// expected-note@-1 {{add '@MainActor' to make var 'globalVar' part of global actor 'MainActor'}}
|
|
// expected-note@-2 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
|
|
// expected-note@-3 {{convert 'globalVar' to a 'let' constant to make 'Sendable' shared state immutable}}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor EscapeArtist {
|
|
var x: Int
|
|
|
|
init(attempt1: Bool) {
|
|
self.x = 0
|
|
|
|
// expected-note@+1 {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
globalVar = self
|
|
|
|
Task { await globalVar!.isolatedMethod() }
|
|
|
|
if self.x == 0 { // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
fatalError("race detected.")
|
|
}
|
|
}
|
|
|
|
init(attempt2: Bool) {
|
|
self.x = 0
|
|
|
|
let wrapped: EscapeArtist? = .some(self) // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
let selfUnchained = wrapped!
|
|
|
|
Task { await selfUnchained.isolatedMethod() }
|
|
if self.x == 0 { // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
fatalError("race detected.")
|
|
}
|
|
}
|
|
|
|
init(attempt3: Bool) {
|
|
self.x = 0
|
|
|
|
let unchainedSelf = self
|
|
|
|
unchainedSelf.nonisolated()
|
|
}
|
|
|
|
init(attempt4: Bool) {
|
|
self.x = 0
|
|
|
|
let unchainedSelf = self
|
|
|
|
unchainedSelf.nonisolated()
|
|
|
|
let _ = { unchainedSelf.nonisolated() }()
|
|
}
|
|
|
|
init(attempt5: Bool) {
|
|
self.x = 0
|
|
|
|
let box = CardboardBox(item: self)
|
|
box.item.nonisolated()
|
|
}
|
|
|
|
init(attempt6: Bool) {
|
|
self.x = 0
|
|
func fn() {
|
|
self.nonisolated()
|
|
}
|
|
fn()
|
|
}
|
|
|
|
func isolatedMethod() { x += 1 }
|
|
nonisolated func nonisolated() {}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
actor Ahmad {
|
|
nonisolated func f() {}
|
|
var prop: Int = 0
|
|
var computedProp: Int { 10 } // expected-note {{property declared here}}
|
|
|
|
init(v1: Void) {
|
|
Task.detached { self.f() } // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
f()
|
|
prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
nonisolated init(v2: Void) async {
|
|
Task.detached { self.f() } // expected-note {{after making a copy of 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
f()
|
|
prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
nonisolated init(v3: Void) async {
|
|
prop = 10
|
|
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
@MainActor init(v4: Void) async {
|
|
prop = 10
|
|
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from this init}}
|
|
prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
deinit {
|
|
// expected-warning@+2 {{actor-isolated property 'computedProp' can not be referenced from a nonisolated context; this is an error in the Swift 6 language mode}}
|
|
// expected-note@+1 {{after accessing property 'computedProp', only nonisolated properties of 'self' can be accessed from a deinit}}
|
|
let x = computedProp
|
|
|
|
prop = x // expected-warning {{cannot access property 'prop' here in deinitializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
actor Rain {
|
|
var x: Int = 0
|
|
nonisolated func f() {}
|
|
|
|
init(_ hollerBack: (Rain) -> () -> Void) {
|
|
defer { self.f() }
|
|
|
|
defer { _ = self.x } // expected-warning {{cannot access property 'x' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
|
|
defer { Task { self.f() } }
|
|
|
|
defer { _ = hollerBack(self) } // expected-note {{after a call involving 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
}
|
|
|
|
init(_ hollerBack: (Rain) -> () -> Void) async {
|
|
defer { self.f() }
|
|
|
|
defer { _ = self.x }
|
|
|
|
defer { Task { self.f() } }
|
|
|
|
defer { _ = hollerBack(self) }
|
|
}
|
|
|
|
deinit {
|
|
x = 1
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
actor NonIsolatedDeinitExceptionForSwift5 {
|
|
var x: Int = 0
|
|
|
|
func cleanup() { // expected-note {{calls to instance method 'cleanup()' from outside of its actor context are implicitly asynchronous}}
|
|
x = 0
|
|
}
|
|
|
|
deinit {
|
|
// expected-warning@+2 {{actor-isolated instance method 'cleanup()' can not be referenced from a nonisolated context; this is an error in the Swift 6 language mode}}
|
|
// expected-note@+1 {{after calling instance method 'cleanup()', only nonisolated properties of 'self' can be accessed from a deinit}}
|
|
cleanup()
|
|
|
|
x = 1 // expected-warning {{cannot access property 'x' here in deinitializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 6.1, *)
|
|
actor IsolatedDeinitExceptionForSwift5 {
|
|
var x: Int = 0
|
|
|
|
func cleanup() {
|
|
x = 0
|
|
}
|
|
|
|
isolated deinit {
|
|
cleanup() // ok
|
|
|
|
x = 1 // ok
|
|
}
|
|
}
|
|
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
actor OhBrother {
|
|
private var giver: (OhBrother) -> Int
|
|
private var whatever: Int = 0
|
|
|
|
static var DefaultResult: Int { 10 }
|
|
|
|
init() {
|
|
// this is OK: we're using DynamicSelfType but that doesn't access protected state.
|
|
self.giver = { (x: OhBrother) -> Int in Self.DefaultResult }
|
|
}
|
|
|
|
init(v2: Void) {
|
|
giver = { (x: OhBrother) -> Int in 0 }
|
|
|
|
// make sure we don't call this a closure, which is the more common situation.
|
|
|
|
_ = giver(self) // expected-note {{after a call involving 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
whatever = 1 // expected-warning {{cannot access property 'whatever' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
|
|
init(v3: Void) {
|
|
let blah = { (x: OhBrother) -> Int in 0 }
|
|
giver = blah
|
|
|
|
_ = blah(self) // expected-note {{after a call involving 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
whatever = 2 // expected-warning {{cannot access property 'whatever' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
@MainActor class AwesomeUIView {}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
class CheckDeinitFromClass: AwesomeUIView {
|
|
var ns: NonSendableType?
|
|
deinit {
|
|
ns?.f() // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType?' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
ns = nil // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType?' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor CheckDeinitFromActor {
|
|
var ns: NonSendableType?
|
|
deinit {
|
|
ns?.f() // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType?' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
ns = nil // expected-warning {{cannot access property 'ns' with a non-Sendable type 'NonSendableType?' from nonisolated deinit; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/70550
|
|
func testActorWithInitAccessorInit() {
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor Angle {
|
|
var degrees: Double
|
|
var radians: Double = 0 {
|
|
@storageRestrictions(initializes: degrees)
|
|
init(initialValue) {
|
|
degrees = initialValue * 180 / .pi
|
|
}
|
|
|
|
get { degrees * .pi / 180 }
|
|
set { degrees = newValue * 180 / .pi }
|
|
}
|
|
|
|
init(degrees: Double) {
|
|
self.degrees = degrees // Ok
|
|
}
|
|
|
|
init(radians: Double) {
|
|
self.radians = radians // Ok
|
|
}
|
|
|
|
init(value: Double) {
|
|
let escapingSelf: (Angle) -> Void = { _ in }
|
|
|
|
// degrees are initialized here via default value associated with radians
|
|
|
|
escapingSelf(self)
|
|
|
|
self.radians = 0
|
|
// expected-warning@-1 {{actor-isolated property 'radians' can not be mutated from a nonisolated context; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor EscapeBeforeFullInit {
|
|
var _a: Int // expected-note {{'self._a' not initialized}}
|
|
|
|
var a: Int {
|
|
@storageRestrictions(initializes: _a)
|
|
init {
|
|
_a = newValue
|
|
}
|
|
|
|
get { _a }
|
|
set { _a = newValue }
|
|
}
|
|
|
|
init(v: Int) {
|
|
let escapingSelf: (EscapeBeforeFullInit) -> Void = { _ in }
|
|
|
|
escapingSelf(self) // expected-error {{'self' used before all stored properties are initialized}}
|
|
// expected-note@-1 {{after a call involving 'self', only nonisolated properties of 'self' can be accessed from this init}}
|
|
|
|
self.a = v
|
|
// expected-warning@-1 {{cannot access property '_a' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor NonisolatedAccessors {
|
|
nonisolated var a: Int = 0 {
|
|
init {
|
|
}
|
|
|
|
get { 0 }
|
|
set {}
|
|
}
|
|
|
|
init(value: Int) {
|
|
let escapingSelf: (NonisolatedAccessors) -> Void = { _ in }
|
|
|
|
// a is initialized here via default value
|
|
|
|
escapingSelf(self)
|
|
|
|
self.a = value // Ok (nonisolated)
|
|
print(a) // Ok (nonisolated)
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor TestNonisolatedUnsafe {
|
|
private nonisolated(unsafe) var child: OtherActor!
|
|
init() {
|
|
child = OtherActor(parent: self)
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.1, *)
|
|
actor OtherActor {
|
|
unowned nonisolated let parent: any Actor
|
|
|
|
init(parent: any Actor) {
|
|
self.parent = parent
|
|
}
|
|
}
|