// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -warn-concurrency // REQUIRES: concurrency let immutableGlobal: String = "hello" var mutableGlobal: String = "can't touch this" // expected-note 5{{var declared here}} @available(SwiftStdlib 5.5, *) func globalFunc() { } @available(SwiftStdlib 5.5, *) func acceptClosure(_: () -> T) { } @available(SwiftStdlib 5.5, *) func acceptConcurrentClosure(_: @Sendable () -> T) { } @available(SwiftStdlib 5.5, *) func acceptEscapingClosure(_: @escaping () -> T) { } @available(SwiftStdlib 5.5, *) func acceptEscapingClosure(_: @escaping (String) -> ()) async -> T? { nil } @available(SwiftStdlib 5.5, *) @discardableResult func acceptAsyncClosure(_: () async -> T) -> T { } @available(SwiftStdlib 5.5, *) func acceptEscapingAsyncClosure(_: @escaping () async -> T) { } @available(SwiftStdlib 5.5, *) func acceptInout(_: inout T) {} // ---------------------------------------------------------------------- // Actor state isolation restrictions // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) actor MySuperActor { var superState: Int = 25 // expected-note {{mutation of this property is only permitted within the actor}} func superMethod() { // expected-note {{calls to instance method 'superMethod()' from outside of its actor context are implicitly asynchronous}} self.superState += 5 } func superAsyncMethod() async { } subscript (index: Int) -> String { "\(index)" } } class Point { var x : Int = 0 var y : Int = 0 } @available(SwiftStdlib 5.5, *) actor MyActor: MySuperActor { // expected-error{{actor types do not support inheritance}} let immutable: Int = 17 // expected-note@+2 2{{property declared here}} // expected-note@+1 6{{mutation of this property is only permitted within the actor}} var mutable: Int = 71 // expected-note@+2 3 {{mutation of this property is only permitted within the actor}} // expected-note@+1 4{{property declared here}} var text: [String] = [] let point : Point = Point() @MainActor var name : String = "koala" // expected-note{{property declared here}} func accessProp() -> String { return self.name // expected-error{{property 'name' isolated to global actor 'MainActor' can not be referenced from actor 'MyActor' in a synchronous context}} } class func synchronousClass() { } static func synchronousStatic() { } func synchronous() -> String { text.first ?? "nothing" } // expected-note 19{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} func asynchronous() async -> String { super.superState += 4 return synchronous() } } @available(SwiftStdlib 5.5, *) actor Camera { func accessProp(act : MyActor) async -> String { return await act.name } } @available(SwiftStdlib 5.5, *) func checkAsyncPropertyAccess() async { let act = MyActor() let _ : Int = await act.mutable + act.mutable act.mutable += 1 // expected-error {{actor-isolated property 'mutable' can only be mutated from inside the actor}} act.superState += 1 // expected-error {{actor-isolated property 'superState' can only be mutated from inside the actor}} act.text[0].append("hello") // expected-error{{actor-isolated property 'text' can only be mutated from inside the actor}} // this is not the same as the above, because Array is a value type var arr = await act.text arr[0].append("hello") act.text.append("no") // expected-error{{actor-isolated property 'text' can only be mutated from inside the actor}} act.text[0] += "hello" // expected-error{{actor-isolated property 'text' can only be mutated from inside the actor}} _ = act.point // expected-warning{{cannot use property 'point' with a non-sendable type 'Point' across actors}} } @available(SwiftStdlib 5.5, *) extension MyActor { nonisolated var actorIndependentVar: Int { get { 5 } set { } } nonisolated func actorIndependentFunc(otherActor: MyActor) -> Int { _ = immutable _ = mutable // expected-error{{actor-isolated property 'mutable' can not be referenced from a non-isolated}} _ = text[0] // expected-error{{actor-isolated property 'text' can not be referenced from a non-isolated context}} _ = synchronous() // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}} // @actorIndependent _ = actorIndependentFunc(otherActor: self) _ = actorIndependentVar actorIndependentVar = 17 _ = self.actorIndependentFunc(otherActor: self) _ = self.actorIndependentVar self.actorIndependentVar = 17 // @actorIndependent on another actor _ = otherActor.actorIndependentFunc(otherActor: self) _ = otherActor.actorIndependentVar otherActor.actorIndependentVar = 17 // async promotion _ = synchronous() // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}} // Global actors syncGlobalActorFunc() /// expected-error{{call to global actor 'SomeGlobalActor'-isolated global function 'syncGlobalActorFunc()' in a synchronous nonisolated context}} _ = syncGlobalActorFunc // Global data is okay if it is immutable. _ = immutableGlobal _ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}} // Partial application _ = synchronous // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}} _ = super.superMethod // expected-error{{actor-isolated instance method 'superMethod()' can not be referenced from a non-isolated context}} acceptClosure(synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}} acceptClosure(self.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}} acceptClosure(otherActor.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} acceptEscapingClosure(synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated context}}}} acceptEscapingClosure(self.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be referenced from a non-isolated}} acceptEscapingClosure(otherActor.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} return 5 } func testAsynchronous(otherActor: MyActor) async { _ = immutable _ = mutable mutable = 0 _ = synchronous() _ = text[0] acceptInout(&mutable) // Accesses on 'self' are okay. _ = self.immutable _ = self.mutable self.mutable = 0 _ = self.synchronous() _ = await self.asynchronous() _ = self.text[0] acceptInout(&self.mutable) _ = self[0] // Accesses on 'super' are okay. _ = super.superState super.superState = 0 acceptInout(&super.superState) super.superMethod() await super.superAsyncMethod() _ = super[0] // Accesses on other actors can only reference immutable data synchronously, // otherwise the access is treated as async _ = otherActor.immutable // okay _ = otherActor.mutable // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{property access is 'async'}} _ = await otherActor.mutable otherActor.mutable = 0 // expected-error{{actor-isolated property 'mutable' can only be mutated on 'self'}} acceptInout(&otherActor.mutable) // expected-error{{actor-isolated property 'mutable' can only be used 'inout' on 'self'}} // expected-error@+2{{actor-isolated property 'mutable' can only be mutated on 'self'}} // expected-warning@+1{{no 'async' operations occur within 'await' expression}} await otherActor.mutable = 0 _ = otherActor.synchronous() // expected-error@-1{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-2{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} _ = await otherActor.asynchronous() _ = otherActor.text[0] // expected-error@-1{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-2{{property access is 'async'}} _ = await otherActor.text[0] // okay // Global data is okay if it is immutable. _ = immutableGlobal _ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}} // Global functions are not actually safe, but we allow them for now. globalFunc() // Class methods are okay. Self.synchronousClass() Self.synchronousStatic() // Global actors syncGlobalActorFunc() // expected-error{{expression is 'async' but is not marked with 'await'}}{{5-5=await }} // expected-note@-1{{calls to global function 'syncGlobalActorFunc()' from outside of its actor context are implicitly asynchronous}} await asyncGlobalActorFunc() // Closures. let localConstant = 17 var localVar = 17 // Non-escaping closures are okay. acceptClosure { _ = text[0] _ = self.synchronous() _ = localVar _ = localConstant } // Concurrent closures might run... concurrently. var otherLocalVar = 12 acceptConcurrentClosure { [otherLocalVar] in defer { _ = otherLocalVar } _ = self.text[0] // expected-error{{actor-isolated property 'text' cannot be referenced from a concurrent closure}} _ = self.mutable // expected-error{{actor-isolated property 'mutable' cannot be referenced from a concurrent closure}} self.mutable = 0 // expected-error{{actor-isolated property 'mutable' cannot be mutated from a concurrent closure}} acceptInout(&self.mutable) // expected-error{{actor-isolated property 'mutable' cannot be used 'inout' from a concurrent closure}} _ = self.immutable _ = self.synchronous() // expected-error{{actor-isolated instance method 'synchronous()' cannot be referenced from a concurrent closure}} _ = localVar // expected-error{{reference to captured var 'localVar' in concurrently-executing code}} localVar = 25 // expected-error{{mutation of captured var 'localVar' in concurrently-executing code}} _ = localConstant _ = otherLocalVar } otherLocalVar = 17 acceptConcurrentClosure { [weak self, otherLocalVar] in defer { _ = self?.actorIndependentVar } _ = otherLocalVar } // Escaping closures are still actor-isolated acceptEscapingClosure { _ = self.text[0] _ = self.mutable self.mutable = 0 acceptInout(&self.mutable) _ = self.immutable _ = self.synchronous() _ = localVar _ = localConstant } // Local functions might run concurrently. @Sendable func localFn1() { _ = self.text[0] // expected-error{{actor-isolated property 'text' cannot be referenced from a concurrent function}} _ = self.synchronous() // expected-error{{actor-isolated instance method 'synchronous()' cannot be referenced from a concurrent function}} _ = localVar // expected-error{{reference to captured var 'localVar' in concurrently-executing code}} localVar = 25 // expected-error{{mutation of captured var 'localVar' in concurrently-executing code}} _ = localConstant } @Sendable func localFn2() { acceptClosure { _ = text[0] // expected-error{{actor-isolated property 'text' cannot be referenced from a concurrent function}} _ = self.synchronous() // expected-error{{actor-isolated instance method 'synchronous()' cannot be referenced from a concurrent function}} _ = localVar // expected-error{{reference to captured var 'localVar' in concurrently-executing code}} localVar = 25 // expected-error{{mutation of captured var 'localVar' in concurrently-executing code}} _ = localConstant } } acceptEscapingClosure { localFn1() localFn2() } localVar = 0 // Partial application _ = synchronous // expected-error{{actor-isolated instance method 'synchronous()' can not be partially applied}} _ = super.superMethod acceptClosure(synchronous) acceptClosure(self.synchronous) acceptClosure(otherActor.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} acceptEscapingClosure(synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be partially applied}} acceptEscapingClosure(self.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can not be partially applied}} acceptEscapingClosure(otherActor.synchronous) // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} acceptAsyncClosure(self.asynchronous) acceptEscapingAsyncClosure(self.asynchronous) } } // ---------------------------------------------------------------------- // Global actor isolation restrictions // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) actor SomeActor { } @globalActor @available(SwiftStdlib 5.5, *) struct SomeGlobalActor { static let shared = SomeActor() } @globalActor @available(SwiftStdlib 5.5, *) struct SomeOtherGlobalActor { static let shared = SomeActor() } @globalActor @available(SwiftStdlib 5.5, *) struct GenericGlobalActor { static var shared: SomeActor { SomeActor() } } @available(SwiftStdlib 5.5, *) @SomeGlobalActor func onions() {} // expected-note{{calls to global function 'onions()' from outside of its actor context are implicitly asynchronous}} @available(SwiftStdlib 5.5, *) @MainActor func beets() { onions() } // expected-error{{call to global actor 'SomeGlobalActor'-isolated global function 'onions()' in a synchronous main actor-isolated context}} // expected-note@-1{{calls to global function 'beets()' from outside of its actor context are implicitly asynchronous}} @available(SwiftStdlib 5.5, *) actor Crystal { // expected-note@+2 {{property declared here}} // expected-note@+1 2 {{mutation of this property is only permitted within the actor}} @SomeGlobalActor var globActorVar : Int = 0 // expected-note@+1 {{mutation of this property is only permitted within the actor}} @SomeGlobalActor var globActorProp : Int { get { return 0 } set {} } @SomeGlobalActor func foo(_ x : inout Int) {} func referToGlobProps() async { _ = await globActorVar + globActorProp globActorProp = 20 // expected-error {{property 'globActorProp' isolated to global actor 'SomeGlobalActor' can not be mutated from actor 'Crystal'}} globActorVar = 30 // expected-error {{property 'globActorVar' isolated to global actor 'SomeGlobalActor' can not be mutated from actor 'Crystal'}} // expected-error@+2 {{property 'globActorVar' isolated to global actor 'SomeGlobalActor' can not be used 'inout' from actor 'Crystal'}} // expected-error@+1 {{actor-isolated property 'globActorVar' cannot be passed 'inout' to implicitly 'async' function call}} await self.foo(&globActorVar) _ = self.foo } } @available(SwiftStdlib 5.5, *) @SomeGlobalActor func syncGlobalActorFunc() { syncGlobalActorFunc() } // expected-note {{calls to global function 'syncGlobalActorFunc()' from outside of its actor context are implicitly asynchronous}} @available(SwiftStdlib 5.5, *) @SomeGlobalActor func asyncGlobalActorFunc() async { await asyncGlobalActorFunc() } @available(SwiftStdlib 5.5, *) @SomeOtherGlobalActor func syncOtherGlobalActorFunc() { } @available(SwiftStdlib 5.5, *) @SomeOtherGlobalActor func asyncOtherGlobalActorFunc() async { await syncGlobalActorFunc() await asyncGlobalActorFunc() } @available(SwiftStdlib 5.5, *) func testGlobalActorClosures() { let _: Int = acceptAsyncClosure { @SomeGlobalActor in syncGlobalActorFunc() syncOtherGlobalActorFunc() // expected-error{{expression is 'async' but is not marked with 'await'}}{{5-5=await }} // expected-note@-1{{calls to global function 'syncOtherGlobalActorFunc()' from outside of its actor context are implicitly asynchronous}} await syncOtherGlobalActorFunc() return 17 } acceptConcurrentClosure { @SomeGlobalActor in 5 } // expected-error{{converting function value of type '@SomeGlobalActor @Sendable () -> Int' to '@Sendable () -> Int' loses global actor 'SomeGlobalActor'}} } @available(SwiftStdlib 5.5, *) extension MyActor { @SomeGlobalActor func onGlobalActor(otherActor: MyActor) async { // Access to other functions in this actor are okay. syncGlobalActorFunc() await asyncGlobalActorFunc() // Other global actors are ok if marked with 'await' await syncOtherGlobalActorFunc() await asyncOtherGlobalActorFunc() _ = immutable _ = mutable // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{property access is 'async'}} _ = await mutable _ = synchronous() // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} _ = await synchronous() _ = text[0] // expected-error{{expression is 'async' but is not marked with 'await'}} // expected-note@-1{{property access is 'async'}} _ = await text[0] // Accesses on 'self' are only okay for immutable and asynchronous, because // we are outside of the actor instance. _ = self.immutable _ = self.synchronous() // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} _ = await self.synchronous() _ = await self.asynchronous() _ = self.text[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{property access is 'async'}} _ = self[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{subscript access is 'async'}} _ = await self.text[0] _ = await self[0] // Accesses on 'super' are not okay without 'await'; we're outside of the actor. _ = super.superState // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{property access is 'async'}} _ = await super.superState super.superMethod() // expected-error{{expression is 'async' but is not marked with 'await'}}{{5-5=await }} // expected-note@-1{{calls to instance method 'superMethod()' from outside of its actor context are implicitly asynchronous}} await super.superMethod() await super.superAsyncMethod() _ = super[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{subscript access is 'async'}} _ = await super[0] // Accesses on other actors can only reference immutable data or // call asychronous methods _ = otherActor.immutable // okay _ = otherActor.synchronous() // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} _ = otherActor.synchronous // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} _ = await otherActor.asynchronous() _ = otherActor.text[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{9-9=await }} // expected-note@-1{{property access is 'async'}} _ = await otherActor.text[0] } } @available(SwiftStdlib 5.5, *) struct GenericStruct { @GenericGlobalActor func f() { } // expected-note {{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}} @GenericGlobalActor func g() { f() // okay } @GenericGlobalActor func h() { f() // expected-error{{call to global actor 'GenericGlobalActor'-isolated instance method 'f()' in a synchronous global actor 'GenericGlobalActor'-isolated context}} let fn = f // expected-note{{calls to let 'fn' from outside of its actor context are implicitly asynchronous}} fn() // expected-error{{call to global actor 'GenericGlobalActor'-isolated let 'fn' in a synchronous global actor 'GenericGlobalActor'-isolated context}} } } @available(SwiftStdlib 5.5, *) extension GenericStruct where T == String { @GenericGlobalActor func h2() { f() g() h() } } @SomeGlobalActor var number: Int = 42 // expected-note {{var declared here}} // expected-note@+1 {{add '@SomeGlobalActor' to make global function 'badNumberUser()' part of global actor 'SomeGlobalActor'}} func badNumberUser() { //expected-error@+1{{var 'number' isolated to global actor 'SomeGlobalActor' can not be referenced from this synchronous context}} print("The protected number is: \(number)") } @available(SwiftStdlib 5.5, *) func asyncBadNumberUser() async { print("The protected number is: \(await number)") } // ---------------------------------------------------------------------- // Non-actor code isolation restrictions // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) func testGlobalRestrictions(actor: MyActor) async { let _ = MyActor() // references to sync methods must be fully applied. _ = actor.synchronous // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced from inside the actor}} _ = actor.asynchronous // any kind of method can be called from outside the actor, so long as it's marked with 'await' _ = actor.synchronous() // expected-error{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-1{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} _ = actor.asynchronous() // expected-error{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-1{{call is 'async'}} _ = await actor.synchronous() _ = await actor.asynchronous() // stored and computed properties can be accessed. Only immutable stored properties can be accessed without 'await' _ = actor.immutable _ = await actor.immutable // expected-warning {{no 'async' operations occur within 'await' expression}} _ = actor.mutable // expected-error{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-1{{property access is 'async'}} _ = await actor.mutable _ = actor.text[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-1{{property access is 'async'}} _ = await actor.text[0] _ = actor[0] // expected-error{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-1{{subscript access is 'async'}} _ = await actor[0] // @actorIndependent declarations are permitted. _ = actor.actorIndependentFunc(otherActor: actor) _ = actor.actorIndependentVar actor.actorIndependentVar = 5 // Operations on non-instances are permitted. MyActor.synchronousStatic() MyActor.synchronousClass() // Global mutable state cannot be accessed. _ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}} // Local mutable variables cannot be accessed from concurrently-executing // code. var i = 17 acceptConcurrentClosure { _ = i // expected-error{{reference to captured var 'i' in concurrently-executing code}} i = 42 // expected-error{{mutation of captured var 'i' in concurrently-executing code}} } print(i) acceptConcurrentClosure { [i] in _ = i } print("\(number)") //expected-error {{expression is 'async' but is not marked with 'await'}}{{12-12=await }} //expected-note@-1{{property access is 'async'}} } @available(SwiftStdlib 5.5, *) func f() { acceptConcurrentClosure { _ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}} } @Sendable func g() { _ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}} } } // ---------------------------------------------------------------------- // Local function isolation restrictions // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) func checkLocalFunctions() async { var i = 0 var j = 0 func local1() { i = 17 } func local2() { // expected-error{{concurrently-executed local function 'local2()' must be marked as '@Sendable'}}{{3-3=@Sendable }} j = 42 } // Okay to call locally. local1() local2() // Non-concurrent closures don't cause problems. acceptClosure { local1() local2() } // Escaping closures can make the local function execute concurrently. acceptConcurrentClosure { local2() } print(i) print(j) var k = 17 func local4() { acceptConcurrentClosure { local3() } } func local3() { // expected-error{{concurrently-executed local function 'local3()' must be marked as '@Sendable'}} k = 25 // expected-error{{mutation of captured var 'k' in concurrently-executing code}} } print(k) } // ---------------------------------------------------------------------- // Lazy properties with initializers referencing 'self' // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) actor LazyActor { var v: Int = 0 // expected-note@-1 6 {{property declared here}} let l: Int = 0 lazy var l11: Int = { v }() lazy var l12: Int = v lazy var l13: Int = { self.v }() lazy var l14: Int = self.v lazy var l15: Int = { [unowned self] in self.v }() // expected-error{{actor-isolated property 'v' can not be referenced from a non-isolated context}} lazy var l21: Int = { l }() lazy var l22: Int = l lazy var l23: Int = { self.l }() lazy var l24: Int = self.l lazy var l25: Int = { [unowned self] in self.l }() nonisolated lazy var l31: Int = { v }() // expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}} nonisolated lazy var l32: Int = v // expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}} nonisolated lazy var l33: Int = { self.v }() // expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}} nonisolated lazy var l34: Int = self.v // expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}} nonisolated lazy var l35: Int = { [unowned self] in self.v }() // expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}} nonisolated lazy var l41: Int = { l }() nonisolated lazy var l42: Int = l nonisolated lazy var l43: Int = { self.l }() nonisolated lazy var l44: Int = self.l nonisolated lazy var l45: Int = { [unowned self] in self.l }() } // Infer global actors from context only for instance members. @available(SwiftStdlib 5.5, *) @MainActor class SomeClassInActor { enum ID: String { case best } func inActor() { } // expected-note{{calls to instance method 'inActor()' from outside of its actor context are implicitly asynchronous}} } @available(SwiftStdlib 5.5, *) extension SomeClassInActor.ID { func f(_ object: SomeClassInActor) { // expected-note{{add '@MainActor' to make instance method 'f' part of global actor 'MainActor'}} object.inActor() // expected-error{{call to main actor-isolated instance method 'inActor()' in a synchronous nonisolated context}} } } // ---------------------------------------------------------------------- // Initializers // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) actor SomeActorWithInits { var mutableState: Int = 17 var otherMutableState: Int init() { self.mutableState = 42 self.otherMutableState = 17 self.isolated() } func isolated() { } } @available(SwiftStdlib 5.5, *) @MainActor class SomeClassWithInits { var mutableState: Int = 17 var otherMutableState: Int static var shared = SomeClassWithInits() // expected-note 2{{static property declared here}} init() { // expected-note{{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}} self.mutableState = 42 self.otherMutableState = 17 self.isolated() } deinit { print(mutableState) // Okay, we're actor-isolated print(SomeClassWithInits.shared) // expected-error{{static property 'shared' isolated to global actor 'MainActor' can not be referenced from this synchronous context}} beets() //expected-error{{call to main actor-isolated global function 'beets()' in a synchronous nonisolated context}} } func isolated() { } static func staticIsolated() { // expected-note{{calls to static method 'staticIsolated()' from outside of its actor context are implicitly asynchronous}} _ = SomeClassWithInits.shared } func hasDetached() { detach { // okay await self.isolated() // expected-warning{{cannot use parameter 'self' with a non-sendable type 'SomeClassWithInits' from concurrently-executed code}} self.isolated() // expected-warning{{cannot use parameter 'self' with a non-sendable type 'SomeClassWithInits' from concurrently-executed code}} // expected-error@-1{{expression is 'async' but is not marked with 'await'}}{{7-7=await }} // expected-note@-2{{calls to instance method 'isolated()' from outside of its actor context are implicitly asynchronous}} print(await self.mutableState) // expected-warning{{cannot use parameter 'self' with a non-sendable type 'SomeClassWithInits' from concurrently-executed code}} } } } @available(SwiftStdlib 5.5, *) func outsideSomeClassWithInits() { // expected-note 3 {{add '@MainActor' to make global function 'outsideSomeClassWithInits()' part of global actor 'MainActor'}} _ = SomeClassWithInits() // expected-error{{call to main actor-isolated initializer 'init()' in a synchronous nonisolated context}} _ = SomeClassWithInits.shared // expected-error{{static property 'shared' isolated to global actor 'MainActor' can not be referenced from this synchronous context}} SomeClassWithInits.staticIsolated() // expected-error{{call to main actor-isolated static method 'staticIsolated()' in a synchronous nonisolated context}} } // ---------------------------------------------------------------------- // Actor protocols. // ---------------------------------------------------------------------- @available(SwiftStdlib 5.5, *) protocol P: Actor { func f() } @available(SwiftStdlib 5.5, *) extension P { func g() { f() } } @available(SwiftStdlib 5.5, *) actor MyActorP: P { func f() { } func h() { g() } } @available(SwiftStdlib 5.5, *) func testCrossActorProtocol(t: T) async { await t.f() await t.g() t.f() // expected-error@-1{{expression is 'async' but is not marked with 'await'}}{{3-3=await }} // expected-note@-2{{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}} t.g() // expected-error@-1{{expression is 'async' but is not marked with 'await'}}{{3-3=await }} // expected-note@-2{{calls to instance method 'g()' from outside of its actor context are implicitly asynchronous}} } // ---------------------------------------------------------------------- // @_inheritActorContext // ---------------------------------------------------------------------- func acceptAsyncSendableClosure(_: @Sendable () async -> T) { } func acceptAsyncSendableClosureInheriting(@_inheritActorContext _: @Sendable () async -> T) { } @available(SwiftStdlib 5.5, *) extension MyActor { func testSendableAndInheriting() { acceptAsyncSendableClosure { synchronous() // expected-error{{expression is 'async' but is not marked with 'await'}} // expected-note@-1{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}} } acceptAsyncSendableClosure { await synchronous() // ok } acceptAsyncSendableClosureInheriting { synchronous() // okay } acceptAsyncSendableClosureInheriting { await synchronous() // expected-warning{{no 'async' operations occur within 'await' expression}} } } } @available(SwiftStdlib 5.5, *) @MainActor // expected-note {{'GloballyIsolatedProto' is isolated to global actor 'MainActor' here}} protocol GloballyIsolatedProto { } // rdar://75849035 - trying to conform an actor to a global-actor isolated protocol should result in an error func test_conforming_actor_to_global_actor_protocol() { @available(SwiftStdlib 5.5, *) actor MyValue : GloballyIsolatedProto {} // expected-error@-1 {{actor 'MyValue' cannot conform to global actor isolated protocol 'GloballyIsolatedProto'}} }