test updates

This commit is contained in:
Michael Gottesman
2024-11-26 14:58:41 -08:00
parent cff835e061
commit c48a9cc72f
9 changed files with 156 additions and 39 deletions

View File

@@ -356,25 +356,17 @@ actor Calculator {
}
@OrangeActor func doSomething() async {
// We will error on the next line when we get past type checking. But since we
// error in the type checker, we do not make further progress.
let _ = (await bananaAdd(1))(2)
// expected-warning@-1{{non-sendable result type '(Int) -> Int' cannot be sent from global actor 'BananaActor'-isolated context in call to global function 'bananaAdd'}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = await (await bananaAdd(1))(2) // expected-warning{{no 'async' operations occur within 'await' expression}}
// expected-warning@-1{{non-sendable result type '(Int) -> Int' cannot be sent from global actor 'BananaActor'-isolated context in call to global function 'bananaAdd'}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let calc = Calculator()
let _ = (await calc.addCurried(1))(2)
// expected-warning@-1{{non-sendable result type '(Int) -> Int' cannot be sent from actor-isolated context in call to instance method 'addCurried'}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = await (await calc.addCurried(1))(2) // expected-warning{{no 'async' operations occur within 'await' expression}}
// expected-warning@-1{{non-sendable result type '(Int) -> Int' cannot be sent from actor-isolated context in call to instance method 'addCurried'}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let plusOne = await calc.addCurried(await calc.add(0, 1))
// expected-warning@-1{{non-sendable result type '(Int) -> Int' cannot be sent from actor-isolated context in call to instance method 'addCurried'}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = plusOne(2)
}

View File

@@ -5,7 +5,7 @@
// REQUIRES: concurrency
// REQUIRES: asserts
class NotConcurrent { } // expected-note 13{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
class NotConcurrent { } // expected-note 12{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
// expected-tns-allow-typechecker-note @-1 {{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
// ----------------------------------------------------------------------
@@ -102,7 +102,7 @@ extension A1 {
_ = other.localLet // expected-warning{{non-sendable type 'NotConcurrent' of property 'localLet' cannot exit actor-isolated context}}
// expected-warning@-1 {{expression is 'async' but is not marked with 'await'}}
// expected-note@-2 {{property access is 'async'}}
_ = await other.synchronous() // expected-warning{{non-sendable result type 'NotConcurrent?' cannot be sent from actor-isolated context in call to instance method 'synchronous()'}}
_ = await other.synchronous() // expected-tns-warning {{non-Sendable 'NotConcurrent?'-typed result can not be returned from actor-isolated instance method 'synchronous()' to actor-isolated context}}
_ = await other.asynchronous(nil)
}
}
@@ -164,7 +164,7 @@ struct HasSubscript {
subscript (i: Int) -> NotConcurrent? { nil }
}
class ClassWithGlobalActorInits { // expected-note 2{{class 'ClassWithGlobalActorInits' does not conform to the 'Sendable' protocol}}
class ClassWithGlobalActorInits { // expected-tns-note 2{{class 'ClassWithGlobalActorInits' does not conform to the 'Sendable' protocol}}
@SomeGlobalActor
init(_: NotConcurrent) { }
@@ -182,10 +182,10 @@ func globalTestMain(nc: NotConcurrent) async {
// expected-tns-note @-1 {{sending global actor 'SomeGlobalActor'-isolated 'a' to global actor 'SomeGlobalActor'-isolated global function 'globalAsync' risks causing data races between global actor 'SomeGlobalActor'-isolated and local main actor-isolated uses}}
await globalSync(a) // expected-tns-note {{access can happen concurrently}}
_ = await ClassWithGlobalActorInits(nc)
// expected-warning @-1 {{non-sendable result type 'ClassWithGlobalActorInits' cannot be sent from global actor 'SomeGlobalActor'-isolated context in call to initializer 'init(_:)'}}
// expected-tns-warning @-1 {{non-Sendable 'ClassWithGlobalActorInits'-typed result can not be returned from global actor 'SomeGlobalActor'-isolated initializer 'init(_:)' to main actor-isolated context}}
// expected-tns-warning @-2 {{sending 'nc' risks causing data races}}
// expected-tns-note @-3 {{sending main actor-isolated 'nc' to global actor 'SomeGlobalActor'-isolated initializer 'init(_:)' risks causing data races between global actor 'SomeGlobalActor'-isolated and main actor-isolated uses}}
_ = await ClassWithGlobalActorInits() // expected-warning{{non-sendable result type 'ClassWithGlobalActorInits' cannot be sent from global actor 'SomeGlobalActor'-isolated context in call to initializer 'init()'}}
_ = await ClassWithGlobalActorInits() // expected-tns-warning {{non-Sendable 'ClassWithGlobalActorInits'-typed result can not be returned from global actor 'SomeGlobalActor'-isolated initializer 'init()' to main actor-isolated context}}
}
@SomeGlobalActor

View File

@@ -7,7 +7,6 @@
@available(SwiftStdlib 5.1, *)
struct NS1 { }
// expected-note @-1 {{consider making struct 'NS1' conform to the 'Sendable' protocol}}
@available(SwiftStdlib 5.1, *)
@available(*, unavailable)
@@ -96,7 +95,7 @@ public actor MyActor: MyProto {
await nonisolatedAsyncFunc1(ns1)
// expected-tns-warning @-1 {{sending 'ns1' risks causing data races}}
// expected-tns-note @-2 {{sending 'self'-isolated 'ns1' to nonisolated global function 'nonisolatedAsyncFunc1' risks causing data races between nonisolated and 'self'-isolated uses}}
_ = await nonisolatedAsyncFunc2() // expected-warning{{non-sendable result type 'NS1' cannot be sent from nonisolated context in call to global function 'nonisolatedAsyncFunc2()'}}
_ = await nonisolatedAsyncFunc2()
}
}

View File

@@ -2,8 +2,7 @@
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/StrictModule.swiftmodule -module-name StrictModule -strict-concurrency=complete %S/Inputs/StrictModule.swift
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/NonStrictModule.swiftmodule -module-name NonStrictModule %S/Inputs/NonStrictModule.swift
// We leave this as just type check since we are checking something that is cross module.
// RUN: %target-swift-frontend -typecheck -strict-concurrency=targeted -disable-availability-checking -I %t 2>&1 %s | %FileCheck %s
// RUN: %target-swift-frontend -c -strict-concurrency=complete -disable-availability-checking -I %t 2>&1 %s | %FileCheck %s
// REQUIRES: concurrency
@@ -15,9 +14,9 @@ actor A {
}
func testA(a: A) async {
_ = await a.f() // CHECK: warning: cannot call function returning non-sendable type '[StrictStruct : NonStrictClass]' across actors}}
// CHECK: note: struct 'StrictStruct' does not conform to the 'Sendable' protocol
// CHECK: note: class 'NonStrictClass' does not conform to the 'Sendable' protocol
_ = await a.f()
// CHECK: warning: non-Sendable '[StrictStruct : NonStrictClass]'-typed result can not be returned from actor-isolated instance method 'f()' to nonisolated context; this is an error in the Swift 6 language mode
// CHECK: note: note: generic struct 'Dictionary' does not conform to the 'Sendable' protocol
}
extension NonStrictStruct: @unchecked Sendable { }

View File

@@ -21,7 +21,7 @@ import _Concurrency
class Klass {}
class NonSendableKlass {
class NonSendableKlass { // expected-note 2{{}}
var klass: Klass
func asyncCall() async
@@ -121,10 +121,6 @@ bb0(%0 : $*{ var NonSendableKlass }):
return %9999 : $()
}
// This doesn't error since the @out parameter is not transferred when it is initialized.
//
// DISCUSSION: The frontend prevents us from using such a value. But we
// shouldn't crash on such values.
sil [ossa] @transfer_does_not_transfer_out_parameters_1 : $@convention(thin) @async () -> () {
bb0:
%0 = alloc_stack $NonSendableKlass
@@ -133,7 +129,7 @@ bb0:
%1 = alloc_stack $NonSendableKlass
%f = function_ref @transferIndirectWithOutResult : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0 // expected-warning {{}}
%useIndirect = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
apply %useIndirect<NonSendableKlass>(%1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
@@ -155,7 +151,7 @@ bb0:
%1 = alloc_stack $NonSendableKlass
%f = function_ref @transferIndirectWithOutResult : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f<NonSendableKlass>(%1, %0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0 // expected-warning {{}}
%f2 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %f2<NonSendableKlass>(%1) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()

View File

@@ -18,7 +18,7 @@ class NonSendableKlass {
class SendableKlass : @unchecked Sendable {}
struct NonSendableStruct { // expected-note {{}}
struct NonSendableStruct {
var ns = NonSendableKlass()
}
@@ -722,7 +722,7 @@ func asyncLetWithoutCapture() async {
//
// NOTE: Error below will go away in next commit.
async let x: NonSendableKlass = await returnValueFromMain()
// expected-warning @-1 {{non-sendable result type 'NonSendableKlass' cannot be sent from main actor-isolated context in call to global function 'returnValueFromMain()'}}
// expected-warning @-1 {{non-Sendable 'NonSendableKlass'-typed result can not be returned from main actor-isolated global function 'returnValueFromMain()' to nonisolated context}}
let y = await x
await transferToMain(y) // expected-warning {{sending 'y' risks causing data races}}
// expected-note @-1 {{sending 'y' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and local nonisolated uses}}
@@ -774,7 +774,6 @@ extension NonSendableStruct {
async let subTask6: NonSendableStruct = self
// expected-warning @-1 {{sending 'self' risks causing data races}}
// expected-note @-2 {{sending 'actor'-isolated 'self' into async let risks causing data races between nonisolated and 'actor'-isolated uses}}
// expected-warning @-3 {{non-sendable result type 'NonSendableStruct' cannot be sent from nonisolated context in call to async function}}
_ = await subTask6
}
}

View File

@@ -14,7 +14,6 @@
*/
class NonSendable {
// expected-note@-1 3{{class 'NonSendable' does not conform to the 'Sendable' protocol}}
var x = 0
}
@@ -31,10 +30,8 @@ func callActorFuncsFromNonisolated(a : A, ns : NonSendable) async {
// Non-sendable value passed from actor isolated to nonisolated
await a.actorTakesNS(ns)
//deferred-warning@-1{{passing argument of non-sendable type 'NonSendable' into actor-isolated context may introduce data races}}
_ = await a.actorRetsNS()
//expected-warning@-1{{non-sendable result type 'NonSendable' cannot be sent from actor-isolated context in call to instance method 'actorRetsNS()'}}
}
@available(SwiftStdlib 5.1, *)
@@ -52,7 +49,6 @@ actor A {
//deferred-warning@-1{{passing argument of non-sendable type 'NonSendable' outside of actor-isolated context may introduce data races}}
_ = await retsNS()
//expected-warning@-1{{non-sendable result type 'NonSendable' cannot be sent from nonisolated context in call to global function 'retsNS()'}}
}
func callActorFuncsFromDiffActor(ns : NonSendable, a : A) async {
@@ -62,6 +58,5 @@ actor A {
//deferred-warning@-1{{passing argument of non-sendable type 'NonSendable' into actor-isolated context may introduce data races}}
_ = await a.actorRetsNS()
//expected-warning@-1{{non-sendable result type 'NonSendable' cannot be sent from actor-isolated context in call to instance method 'actorRetsNS()'}}
}
}

View File

@@ -0,0 +1,137 @@
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -swift-version 6 -parse-as-library %s -emit-sil -o /dev/null -verify
// REQUIRES: asserts
// REQUIRES: concurrency
///////////////////////
// MARK: Declaration //
///////////////////////
actor Custom {
}
@globalActor
struct CustomActor {
static var shared: Custom {
return Custom()
}
}
class NonSendable {} // expected-note 3{{}}
func passNonSendable(_: NonSendable) async { }
func returnsNonSendable() async -> NonSendable { NonSendable() }
@MainActor
func mainActorPassNonSendable(_: NonSendable) async { }
@MainActor
func mainActorReturnNonSendable() async -> NonSendable { NonSendable() }
@MainActor
func mainActorGenericPassNonSendable<T>(_: T) async { }
@MainActor
func mainActorGenericReturnNonSendable<T>() async -> T { fatalError() }
@MainActor
func mainActorAsyncFunc3() async -> ((Int) -> Int) {
return { (_ y: Int) in y }
}
/////////////////
// MARK: Tests //
/////////////////
@MainActor func mainActorResult(_ x : Int) -> ((Int) -> Int) {
return { (_ y : Int) in x + y }
}
actor Calculator {
func addCurried(_ x : Int) -> ((Int) -> Int) {
return { (_ y : Int) in x + y }
}
func add(_ x : Int, _ y : Int) -> Int {
return x + y
}
}
@CustomActor
func testActorCrossingBoundary() async {
let _ = (await mainActorResult(1))(5)
// expected-error @-1 {{non-Sendable '(Int) -> Int'-typed result can not be returned from main actor-isolated global function 'mainActorResult' to global actor 'CustomActor'-isolated context}}
// expected-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = await (await mainActorResult(1))(2)
// expected-error @-1 {{non-Sendable '(Int) -> Int'-typed result can not be returned from main actor-isolated global function 'mainActorResult' to global actor 'CustomActor'-isolated context}}
// expected-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
// expected-warning @-3 {{no 'async' operations occur within 'await' expression}}
let calc = Calculator()
let _ = (await calc.addCurried(1))(2)
// expected-error @-1 {{non-Sendable '(Int) -> Int'-typed result can not be returned from actor-isolated instance method 'addCurried' to global actor 'CustomActor'-isolated context}}
// expected-note@-2{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = await (await calc.addCurried(1))(2) // expected-warning{{no 'async' operations occur within 'await' expression}}
// expected-error @-1 {{non-Sendable '(Int) -> Int'-typed result can not be returned from actor-isolated instance method 'addCurried' to global actor 'CustomActor'-isolated context}}
// expected-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let plusOne = await calc.addCurried(await calc.add(0, 1))
// expected-error @-1 {{non-Sendable '(Int) -> Int'-typed result can not be returned from actor-isolated instance method 'addCurried' to global actor 'CustomActor'-isolated context}}
// expected-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
let _ = plusOne(2)
}
actor A {
let actorNS = NonSendable()
func actorTakesNS(_ : NonSendable) async {}
func actorRetsNS() async -> NonSendable { NonSendable() }
func callNonisolatedFuncsFromActor(ns: NonSendable) async {
// Non-sendable value passed from nonisolated to actor isolated
await passNonSendable(ns)
// expected-error @-1 {{sending 'ns' risks causing data races}}
// expected-note @-2 {{sending 'self'-isolated 'ns' to nonisolated global function 'passNonSendable' risks causing data races between nonisolated and 'self'-isolated uses}}
_ = await returnsNonSendable()
}
func callActorFuncsFromDiffActor(ns : NonSendable, a : A) async {
// Non-sendable value passed between the isolation of two different actors
await a.actorTakesNS(ns)
// expected-error @-1 {{sending 'ns' risks causing data races}}
// expected-note @-2 {{sending 'self'-isolated 'ns' to actor-isolated instance method 'actorTakesNS' risks causing data races between actor-isolated and 'self'-isolated uses}}
_ = await a.actorRetsNS()
// expected-error @-1 {{non-Sendable 'NonSendable'-typed result can not be returned from actor-isolated instance method 'actorRetsNS()' to actor-isolated context}}
}
func validateErrorForPassingIsolatedNonSendable(_ ns: NonSendable) async {
await mainActorGenericPassNonSendable(ns)
// expected-error @-1 {{sending 'ns' risks causing data races}}
// expected-note @-2 {{sending 'self'-isolated 'ns' to main actor-isolated global function 'mainActorGenericPassNonSendable' risks causing data races between main actor-isolated and 'self'-isolated uses}}
}
func validateErrorReturningFromNonIsolated() async {
let _ = await returnsNonSendable()
}
}
func callActorFuncsFromNonisolated(a : A, ns : NonSendable) async {
await a.actorTakesNS(ns)
// expected-error @-1 {{sending 'ns' risks causing data races}}
// expected-note @-2 {{sending task-isolated 'ns' to actor-isolated instance method 'actorTakesNS' risks causing data races between actor-isolated and task-isolated uses}}
_ = await a.actorRetsNS()
// expected-error @-1 {{non-Sendable 'NonSendable'-typed result can not be returned from actor-isolated instance method 'actorRetsNS()' to nonisolated context}}
}
func testGenericResults() async {
let _: NonSendable = await mainActorGenericReturnNonSendable()
// expected-error @-1 {{non-Sendable 'NonSendable'-typed result can not be returned from main actor-isolated global function 'mainActorGenericReturnNonSendable()' to nonisolated context}}
}

View File

@@ -238,7 +238,7 @@ func asyncLetReabstractionThunkTest() async {
func asyncLetReabstractionThunkTest2() async {
// We emit the error here since we are returning a main actor isolated value.
async let newValue: NonSendableKlass = await getMainActorValueAsync()
// expected-warning @-1 {{non-sendable result type 'NonSendableKlass' cannot be sent from main actor-isolated context in call to global function 'getMainActorValueAsync()'}}
// expected-warning @-1 {{non-Sendable 'NonSendableKlass'-typed result can not be returned from main actor-isolated global function 'getMainActorValueAsync()' to nonisolated context}}
let _ = await newValue
@@ -261,7 +261,7 @@ func asyncLetReabstractionThunkTest2() async {
@MainActor func asyncLetReabstractionThunkTestGlobalActor2() async {
// We emit the error here since we are returning a main actor isolated value.
async let newValue: NonSendableKlass = await getMainActorValueAsync()
// expected-warning @-1 {{non-sendable result type 'NonSendableKlass' cannot be sent from main actor-isolated context in call to global function 'getMainActorValueAsync()'}}
// expected-warning @-1 {{non-Sendable 'NonSendableKlass'-typed result can not be returned from main actor-isolated global function 'getMainActorValueAsync()' to nonisolated context}}
let _ = await newValue