mirror of
https://github.com/apple/swift.git
synced 2026-10-12 14:50:47 +02:00
The opaque values test coverage I initially added will emit to stdout, which is noisy for people's logs if the test is failing for some other reason.
92 lines
4.2 KiB
Swift
92 lines
4.2 KiB
Swift
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen-ossa -o /dev/null -sil-verify-all -enable-sil-opaque-values %s -module-name test -swift-version 5 -target %target-swift-5.1-abi-triple -parse-stdlib -sil-verify-all
|
|
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-sil %s -module-name test -swift-version 5 -target %target-swift-5.1-abi-triple -parse-stdlib -sil-verify-all | %FileCheck %s --check-prefix=CHECK
|
|
// REQUIRES: concurrency
|
|
|
|
import Swift
|
|
import _Concurrency
|
|
|
|
// Verify that hop_to_executor is emitted after
|
|
// await_async_continuation in the resume (and error) blocks.
|
|
// Without this hop, nonisolated(nonsending) functions that use continuation
|
|
// builtins would incorrectly just continue on whichever thread resumed the continuation.
|
|
|
|
// === Nonisolated free function (Swift 5 default) — hops to generic executor ===
|
|
|
|
// CHECK-LABEL: // nonisolatedFree()
|
|
// CHECK: sil @$s4test15nonisolatedFreeSiyYaF
|
|
// CHECK: [[GLOBAL:%[0-9]+]] = enum $Optional<any Actor>, #Optional.none
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[GLOBAL]] : $Optional<any Actor>
|
|
public func nonisolatedFree() async -> Int {
|
|
return await Builtin.withUnsafeContinuation { c in }
|
|
}
|
|
|
|
// === nonisolated(nonsending) free function — hops to caller's implicit actor ===
|
|
|
|
// CHECK-LABEL: // nonsendingFree()
|
|
// CHECK: sil @$s4test14nonsendingFreeSiyYaF
|
|
// CHECK: bb0([[IMPLICIT:%[0-9]+]] : $Builtin.ImplicitActor):
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[IMPLICIT]] : $Builtin.ImplicitActor
|
|
public nonisolated(nonsending) func nonsendingFree() async -> Int {
|
|
return await Builtin.withUnsafeContinuation { c in }
|
|
}
|
|
|
|
// === @concurrent free function — hops to generic executor ===
|
|
|
|
// CHECK-LABEL: // concurrentFree()
|
|
// CHECK: sil @$s4test14concurrentFreeSiyYaF
|
|
// CHECK: [[GLOBAL:%[0-9]+]] = enum $Optional<any Actor>, #Optional.none
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[GLOBAL]] : $Optional<any Actor>
|
|
@concurrent
|
|
public func concurrentFree() async -> Int {
|
|
return await Builtin.withUnsafeContinuation { c in }
|
|
}
|
|
|
|
// === @MainActor class method — hops to MainActor ===
|
|
|
|
@MainActor
|
|
public class MainActorClass {
|
|
// CHECK-LABEL: // MainActorClass.mainActorMethod()
|
|
// CHECK: sil @$s4test14MainActorClassC04mainC6MethodSiyYaF
|
|
// CHECK: [[MA:%[0-9]+]] = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[MA]] : $MainActor
|
|
public func mainActorMethod() async -> Int {
|
|
return await Builtin.withUnsafeContinuation { c in }
|
|
}
|
|
}
|
|
|
|
// === actor method — hops to actor executor ===
|
|
|
|
public actor MyActor {
|
|
// CHECK-LABEL: // MyActor.actorMethod()
|
|
// CHECK: sil @$s4test7MyActorC11actorMethodSiyYaF
|
|
// CHECK: bb0([[SELF:%[0-9]+]] : $MyActor):
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[SELF]] : $MyActor
|
|
public func actorMethod() async -> Int {
|
|
return await Builtin.withUnsafeContinuation { c in }
|
|
}
|
|
}
|
|
|
|
// === Throwing: nonisolated(nonsending) — hops in both resume and error blocks ===
|
|
|
|
// CHECK-LABEL: // nonsendingThrowing()
|
|
// CHECK: sil @$s4test18nonsendingThrowingSiyYaKF
|
|
// CHECK: bb0([[IMPLICIT:%[0-9]+]] : $Builtin.ImplicitActor):
|
|
// CHECK: await_async_continuation {{%[0-9]+}} : $Builtin.RawUnsafeContinuation, resume [[RESUME:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
|
|
// CHECK: [[RESUME]]:
|
|
// CHECK-NEXT: hop_to_executor [[IMPLICIT]] : $Builtin.ImplicitActor
|
|
// CHECK: [[ERROR]]({{%[0-9]+}} : $any Error):
|
|
// CHECK-NEXT: hop_to_executor [[IMPLICIT]] : $Builtin.ImplicitActor
|
|
public nonisolated(nonsending) func nonsendingThrowing() async throws -> Int {
|
|
return try await Builtin.withUnsafeThrowingContinuation { c in }
|
|
}
|