mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sometimes features are removed from `Features.def`, but they are not removed from the test files. The compiler ignores every feature that does not exist. This leads to removed features still being tested, and with the introduction of #76740, `REQUIRED:`. Modify the code that generates the active feature set for testing to also generate the set of existing features, and pass this list of existing features to the verifier script. If a feature is trying to be activated and does not exist, the verifier will warn the user. - `SwiftParser` feature was renamed `ParserASTGen`, but some tests were using both spellings. Remove the mentions of `SwiftParser` in the tests. - `ImportObjcForwardDeclarations` was spelled with upper case `C` in a couple of tests. Fix it so the matching is easier. - `TransferringArgsAndResults` was an experimental feature that was removed. - Ignore the usage of inexisting feature in `swift-export-as.swift` because it seems to be what the test is actually testing. - Ignore the test `availability_define.swift` because it tests the pseudo-feature `AvailabilityMacro=` which is not part of `Features.def`.
250 lines
8.8 KiB
Swift
250 lines
8.8 KiB
Swift
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify %s -o /dev/null -parse-as-library
|
|
|
|
// REQUIRES: concurrency
|
|
|
|
////////////////////////
|
|
// MARK: Declarations //
|
|
////////////////////////
|
|
|
|
class NonSendableKlass {}
|
|
|
|
func useValue<T>(_ t: T) {}
|
|
func useValueAsync<T>(_ t: T) async {}
|
|
|
|
/////////////////
|
|
// MARK: Tests //
|
|
/////////////////
|
|
|
|
@MainActor
|
|
func withCheckedContinuation_1() async -> NonSendableKlass {
|
|
await withCheckedContinuation { continuation in
|
|
continuation.resume(returning: NonSendableKlass())
|
|
}
|
|
}
|
|
|
|
func withCheckedContinuation_1a() async -> NonSendableKlass {
|
|
await withCheckedContinuation { continuation in
|
|
continuation.resume(returning: NonSendableKlass())
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func withCheckedContinuation_2() async -> NonSendableKlass {
|
|
await withCheckedContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
func withCheckedContinuation_2a() async -> NonSendableKlass {
|
|
await withCheckedContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func withCheckedContinuation_3() async {
|
|
// x is main actor isolated since withCheckedContinuation is #isolated.
|
|
let x = await withCheckedContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
|
|
// Since x is returned as sending from withCheckedContinuation, we can send it
|
|
// further.
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
func withCheckedContinuation_3a() async {
|
|
let x = await withCheckedContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
|
|
// This is ok since x is disconnected.
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
@MainActor
|
|
func withCheckedContinuation_4() async {
|
|
// x is main actor isolated since withCheckedContinuation is #isolated.
|
|
let y = NonSendableKlass()
|
|
let x = await withCheckedContinuation { continuation in
|
|
continuation.resume(returning: y)
|
|
// expected-error @-1 {{sending 'y' risks causing data races}}
|
|
// expected-note @-2 {{main actor-isolated 'y' is passed as a 'sending' parameter}}
|
|
useValue(y)
|
|
}
|
|
|
|
// Since withCheckedContinuation returns value as sending, we can call
|
|
// useValueAsync since it is disconnected.
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
func withCheckedContinuation_4a() async {
|
|
// x is main actor isolated since withCheckedContinuation is #isolated.
|
|
let y = NonSendableKlass()
|
|
let x = await withCheckedContinuation { continuation in
|
|
continuation.resume(returning: y)
|
|
// expected-error @-1 {{sending 'y' risks causing data races}}
|
|
// expected-note @-2 {{task-isolated 'y' is passed as a 'sending' parameter}}
|
|
useValue(y)
|
|
}
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
@MainActor func testAsyncStream() {
|
|
let (_, continuation) = AsyncStream.makeStream(of: NonSendableKlass.self)
|
|
|
|
continuation.yield(NonSendableKlass())
|
|
let x = NonSendableKlass()
|
|
continuation.yield(x) // expected-error {{sending 'x' risks causing data races}}
|
|
// expected-note @-1 {{'x' used after being passed as a 'sending' parameter; Later uses could race}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
|
|
@MainActor func testAsyncStreamContinuation() {
|
|
let _ = AsyncStream(NonSendableKlass.self) { continuation in
|
|
continuation.yield(NonSendableKlass())
|
|
let x = NonSendableKlass()
|
|
continuation.yield(x) // expected-error {{sending 'x' risks causing data races}}
|
|
// expected-note @-1 {{'x' used after being passed as a 'sending' parameter; Later uses could race}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
@MainActor func testAsyncThrowingStream() {
|
|
let (_, continuation) = AsyncThrowingStream.makeStream(of: NonSendableKlass.self)
|
|
|
|
continuation.yield(NonSendableKlass())
|
|
let x = NonSendableKlass()
|
|
continuation.yield(x) // expected-error {{sending 'x' risks causing data races}}
|
|
// expected-note @-1 {{'x' used after being passed as a 'sending' parameter; Later uses could race}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
|
|
@MainActor func testAsyncThrowingStreamContinuation() {
|
|
let _ = AsyncThrowingStream(NonSendableKlass.self) { continuation in
|
|
continuation.yield(NonSendableKlass())
|
|
let x = NonSendableKlass()
|
|
continuation.yield(x) // expected-error {{sending 'x' risks causing data races}}
|
|
// expected-note @-1 {{'x' used after being passed as a 'sending' parameter; Later uses could race}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func withUnsafeContinuation_1() async -> NonSendableKlass {
|
|
await withUnsafeContinuation { continuation in
|
|
continuation.resume(returning: NonSendableKlass())
|
|
}
|
|
}
|
|
|
|
func withUnsafeContinuation_1a() async -> NonSendableKlass {
|
|
await withUnsafeContinuation { continuation in
|
|
continuation.resume(returning: NonSendableKlass())
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func withUnsafeContinuation_2() async -> NonSendableKlass {
|
|
await withUnsafeContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
func withUnsafeContinuation_2a() async -> NonSendableKlass {
|
|
await withUnsafeContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func withUnsafeContinuation_3() async {
|
|
// x is main actor isolated since withUnsafeContinuation is #isolated.
|
|
let x = await withUnsafeContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
|
|
// withUnsafeContinuation returns x as sending, so we can pass it to a
|
|
// nonisolated function.
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
func withUnsafeContinuation_3a() async {
|
|
let x = await withUnsafeContinuation { continuation in
|
|
let x = NonSendableKlass()
|
|
continuation.resume(returning: x)
|
|
// expected-error @-1 {{sending 'x' risks causing data races}}
|
|
// expected-note @-2 {{'x' used after being passed as a 'sending' parameter}}
|
|
useValue(x) // expected-note {{access can happen concurrently}}
|
|
}
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
@MainActor
|
|
func withUnsafeContinuation_4() async {
|
|
// x is main actor isolated since withUnsafeContinuation is #isolated.
|
|
let y = NonSendableKlass()
|
|
let x = await withUnsafeContinuation { continuation in
|
|
continuation.resume(returning: y)
|
|
// expected-error @-1 {{sending 'y' risks causing data races}}
|
|
// expected-note @-2 {{main actor-isolated 'y' is passed as a 'sending' parameter}}
|
|
useValue(y)
|
|
}
|
|
|
|
// Since withUnsafeContinuation returns x as sending, we can use it in a
|
|
// nonisolated function.
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
func withUnsafeContinuation_4a() async {
|
|
// x is main actor isolated since withUnsafeContinuation is #isolated.
|
|
let y = NonSendableKlass()
|
|
let x = await withUnsafeContinuation { continuation in
|
|
continuation.resume(returning: y)
|
|
// expected-error @-1 {{sending 'y' risks causing data races}}
|
|
// expected-note @-2 {{task-isolated 'y' is passed as a 'sending' parameter}}
|
|
useValue(y)
|
|
}
|
|
await useValueAsync(x)
|
|
}
|
|
|
|
public actor WithCheckedThrowingContinuationErrorAvoidance {
|
|
nonisolated func handle(reply: (Int) -> Void) {}
|
|
|
|
// make sure that we do not emit any errors on the following code.
|
|
func noError() async throws -> Int {
|
|
return try await withCheckedThrowingContinuation { continuation in
|
|
handle { result in
|
|
continuation.resume(returning: result)
|
|
}
|
|
}
|
|
}
|
|
}
|