mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
293 lines
11 KiB
Swift
293 lines
11 KiB
Swift
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix old- %s -o /dev/null
|
|
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix new- -enable-upcoming-feature ImmutableWeakCaptures %s -o /dev/null
|
|
|
|
// This test validates the behavior of transfer non sendable around ownership
|
|
// constructs like non copyable types, consuming/borrowing parameters, and inout
|
|
// parameters.
|
|
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: swift_feature_ImmutableWeakCaptures
|
|
|
|
final class S: Sendable {
|
|
func foo() {}
|
|
}
|
|
|
|
// expected-old-note@+2 13{{class 'NS' does not conform to the 'Sendable' protocol}}
|
|
// expected-new-note@+1 12{{class 'NS' does not conform to the 'Sendable' protocol}}
|
|
final class NS {
|
|
func bar() {}
|
|
}
|
|
|
|
func getS() -> S { S() }
|
|
func getNS() -> NS { NS() }
|
|
|
|
final class CheckOptionality1: Sendable {
|
|
// expected-old-error@+4 {{'weak' variable should have optional type 'S?'}}
|
|
// expected-old-error@+3 {{stored property 'x' of 'Sendable'-conforming class 'CheckOptionality1' is mutable}}
|
|
// expected-new-error@+2 {{'weak' variable should have optional type 'S?'}}
|
|
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckOptionality1' is mutable}}
|
|
weak var x: S = getS()
|
|
}
|
|
|
|
final class CheckOptionality2: Sendable {
|
|
// expected-error@+1 {{'weak' variable should have optional type 'S?'}}
|
|
weak let x: S = getS()
|
|
}
|
|
|
|
final class CheckSendability1: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
|
|
weak var x: S? = nil
|
|
|
|
weak var y: S? {
|
|
get { x }
|
|
set { x = newValue }
|
|
}
|
|
}
|
|
|
|
final class CheckSendability2: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
|
|
weak var x: NS? = nil
|
|
}
|
|
|
|
final class CheckSendability3: Sendable {
|
|
weak let x: S? = nil
|
|
}
|
|
|
|
final class CheckSendability4: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
|
|
weak let x: NS? = nil
|
|
}
|
|
|
|
final class CheckSendability5: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
|
|
unowned var x: S = getS()
|
|
}
|
|
|
|
final class CheckSendability6: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
|
|
unowned var x: NS = getNS()
|
|
}
|
|
|
|
final class CheckSendability7: Sendable {
|
|
unowned let x: S = getS()
|
|
}
|
|
|
|
final class CheckSendability8: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability8' has non-Sendable type 'NS'}}
|
|
unowned let x: NS = getNS()
|
|
}
|
|
|
|
final class CheckSendability9: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
|
|
unowned(unsafe) var x: S = getS()
|
|
}
|
|
|
|
final class CheckSendability10: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
|
|
unowned(unsafe) var x: NS = getNS()
|
|
}
|
|
|
|
final class CheckSendability11: Sendable {
|
|
unowned(unsafe) let x: S = getS()
|
|
}
|
|
|
|
final class CheckSendability12: Sendable {
|
|
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability12' has non-Sendable type 'NS'}}
|
|
unowned(unsafe) let x: NS = getNS()
|
|
}
|
|
|
|
|
|
func checkWeakCapture1(_ strongRef: S) -> @Sendable () -> Void {
|
|
// expected-warning@+1 {{weak variable 'weakRef' was never mutated; consider changing to 'let' constant}}
|
|
weak var weakRef: S? = strongRef
|
|
return {
|
|
// expected-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
|
|
weakRef?.foo()
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture2(_ strongRef: S) -> @Sendable () -> Void {
|
|
weak let weakRef: S? = strongRef
|
|
return {
|
|
weakRef?.foo()
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture3(_ strongRef: S) -> @Sendable () -> Void {
|
|
return { [weak weakRef = strongRef] in
|
|
// TODO: Add expected old error, when https://github.com/swiftlang/swift/issues/80014 is fixed
|
|
// See also https://forums.swift.org/t/lets-debug-missing-rbi-data-race-diagnostics/78910
|
|
weakRef?.foo()
|
|
// expected-new-error@+1 {{cannot assign to value: 'weakRef' is an immutable capture}}
|
|
weakRef = nil
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
|
|
// expected-warning@+1 {{weak variable 'weakRef' was never mutated; consider changing to 'let' constant}}
|
|
weak var weakRef: NS? = strongRef
|
|
return {
|
|
// expected-error@+2 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
|
|
// expected-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
|
|
weakRef?.bar()
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture5(_ strongRef: NS) -> @Sendable () -> Void {
|
|
weak let weakRef: NS? = strongRef
|
|
return {
|
|
// expected-error@+1 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
|
|
weakRef?.bar()
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture6(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [weak weakRef = strongRef] in
|
|
// expected-old-error@+3 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
|
|
// For some reason the next error masks this error.
|
|
// This case is split into two, to verify that when unmasked error is triggered.
|
|
weakRef?.bar()
|
|
// expected-new-error@+1 {{cannot assign to value: 'weakRef' is an immutable capture}}
|
|
weakRef = nil
|
|
}
|
|
}
|
|
|
|
func checkWeakCapture7(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [weak weakRef = strongRef] in
|
|
// expected-error@+1 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
|
|
weakRef?.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture1(_ strongRef: S) -> @Sendable () -> Void {
|
|
// expected-old-warning@+2 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
// expected-new-warning@+1 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
unowned var unownedRef: S = strongRef
|
|
return {
|
|
// expected-old-error@+2 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
// expected-new-error@+1 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
unownedRef.foo()
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture2(_ strongRef: S) -> @Sendable () -> Void {
|
|
unowned let unownedRef: S = strongRef
|
|
return {
|
|
unownedRef.foo()
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture3(_ strongRef: S) -> @Sendable () -> Void {
|
|
return { [unowned unownedRef = strongRef] in
|
|
// TODO: Add expected old error, when https://github.com/swiftlang/swift/issues/80014 is fixed
|
|
// See also https://forums.swift.org/t/lets-debug-missing-rbi-data-race-diagnostics/78910
|
|
unownedRef.foo()
|
|
// expected-old-error@+2 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
// expected-new-error@+1 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
unownedRef = strongRef
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture4(_ strongRef: NS) -> @Sendable () -> Void {
|
|
// expected-old-warning@+2 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
// expected-new-warning@+1 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
unowned var unownedRef: NS = strongRef
|
|
return {
|
|
// expected-error@+2 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
// expected-error@+1 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture5(_ strongRef: NS) -> @Sendable () -> Void {
|
|
unowned let unownedRef: NS = strongRef
|
|
return {
|
|
// expected-error@+1 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture6(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [unowned unownedRef = strongRef] in
|
|
// For some reason the next error masks this error.
|
|
// This case is split into two, to verify that when unmasked error is triggered.
|
|
unownedRef.bar()
|
|
// expected-old-error@+2 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
// expected-new-error@+1 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
unownedRef = strongRef
|
|
}
|
|
}
|
|
|
|
func checkUnownedCapture7(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [unowned unownedRef = strongRef] in
|
|
// expected-error@+1 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture1(_ strongRef: S) -> @Sendable () -> Void {
|
|
// expected-old-warning@+2 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
// expected-new-warning@+1 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
unowned(unsafe) var unownedRef: S = strongRef
|
|
return {
|
|
// expected-old-error@+2 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
// expected-new-error@+1 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
unownedRef.foo()
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture2(_ strongRef: S) -> @Sendable () -> Void {
|
|
unowned(unsafe) let unownedRef: S = strongRef
|
|
return {
|
|
unownedRef.foo()
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture3(_ strongRef: S) -> @Sendable () -> Void {
|
|
return { [unowned(unsafe) unownedRef = strongRef] in
|
|
// TODO: Add expected old error, when https://github.com/swiftlang/swift/issues/80014 is fixed
|
|
// See also https://forums.swift.org/t/lets-debug-missing-rbi-data-race-diagnostics/78910
|
|
unownedRef.foo()
|
|
// expected-old-error@+2 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
// expected-new-error@+1 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
unownedRef = strongRef
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture4(_ strongRef: NS) -> @Sendable () -> Void {
|
|
// expected-old-warning@+2 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
// expected-new-warning@+1 {{variable 'unownedRef' was never mutated; consider changing to 'let' constant}}
|
|
unowned(unsafe) var unownedRef: NS = strongRef
|
|
return {
|
|
// expected-error@+2 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
// expected-error@+1 {{reference to captured var 'unownedRef' in concurrently-executing code}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture5(_ strongRef: NS) -> @Sendable () -> Void {
|
|
unowned(unsafe) let unownedRef: NS = strongRef
|
|
return {
|
|
// expected-error@+1 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture6(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [unowned(unsafe) unownedRef = strongRef] in
|
|
// For some reason the next error masks this error.
|
|
// This case is split into two, to verify that when unmasked error is triggered.
|
|
unownedRef.bar()
|
|
// expected-old-error@+2 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
// expected-new-error@+1 {{cannot assign to value: 'unownedRef' is an immutable capture}}
|
|
unownedRef = strongRef
|
|
}
|
|
}
|
|
|
|
func checkUnsafeCapture7(_ strongRef: NS) -> @Sendable () -> Void {
|
|
return { [unowned(unsafe) unownedRef = strongRef] in
|
|
// expected-error@+1 {{capture of 'unownedRef' with non-Sendable type 'NS' in a '@Sendable' closure}}
|
|
unownedRef.bar()
|
|
}
|
|
}
|