Skip to content

Commit 6295637

Browse files
committed
Allow using non-escapable types as suites.
This PR enables using non-escapable types as suites. For example: ```swift @suite struct NumberOfBeesTests: ~Escapable { @test borrowing func countBees() { ... } } ``` Non-escapable types have a number of constraints in Swift, and those constraints aren't lifted in a test target, but generally speaking a non-escapable type should be able to do all the things any other type can do _as a test suite_.
1 parent 69a1e26 commit 6295637

File tree

6 files changed

+25
-27
lines changed

6 files changed

+25
-27
lines changed

Package.swift

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ extension Array where Element == PackageDescription.SwiftSetting {
171171
.unsafeFlags(["-require-explicit-sendable"]),
172172
.enableUpcomingFeature("ExistentialAny"),
173173
.enableExperimentalFeature("SuppressedAssociatedTypes"),
174+
.enableExperimentalFeature("LifetimeDependence"),
174175

175176
.enableExperimentalFeature("AccessLevelOnImport"),
176177
.enableUpcomingFeature("InternalImportsByDefault"),

Sources/Testing/Parameterization/TypeInfo.swift

+6-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public struct TypeInfo: Sendable {
1818
///
1919
/// - Parameters:
2020
/// - type: The concrete metatype.
21-
case type(_ type: any ~Copyable.Type)
21+
case type(_ type: any (~Copyable & ~Escapable).Type)
2222

2323
/// The type info represents a metatype, but a reference to that metatype is
2424
/// not available at runtime.
@@ -38,7 +38,7 @@ public struct TypeInfo: Sendable {
3838
///
3939
/// If this instance was created from a type name, or if it was previously
4040
/// encoded and decoded, the value of this property is `nil`.
41-
public var type: (any ~Copyable.Type)? {
41+
public var type: (any (~Copyable & ~Escapable).Type)? {
4242
if case let .type(type) = _kind {
4343
return type
4444
}
@@ -79,7 +79,7 @@ public struct TypeInfo: Sendable {
7979
///
8080
/// - Parameters:
8181
/// - type: The type which this instance should describe.
82-
init(describing type: any ~Copyable.Type) {
82+
init(describing type: any (~Copyable & ~Escapable).Type) {
8383
_kind = .type(type)
8484
}
8585

@@ -265,11 +265,9 @@ extension TypeInfo {
265265
}
266266
switch _kind {
267267
case let .type(type):
268-
#if compiler(>=6.1)
269-
return _mangledTypeName(type)
270-
#else
268+
// _mangledTypeName() works with non-escaping types, but its signature has
269+
// not been updated yet. SEE: rdar://145945680
271270
return _mangledTypeName(unsafeBitCast(type, to: Any.Type.self))
272-
#endif
273271
case let .nameOnly(_, _, mangledName):
274272
return mangledName
275273
}
@@ -379,7 +377,7 @@ extension ObjectIdentifier {
379377
///
380378
/// - Bug: The standard library should support this conversion.
381379
/// ([134276458](rdar://134276458), [134415960](rdar://134415960))
382-
fileprivate init(_ type: any ~Copyable.Type) {
380+
fileprivate init(_ type: any (~Copyable & ~Escapable).Type) {
383381
self.init(unsafeBitCast(type, to: Any.Type.self))
384382
}
385383
}

Sources/Testing/Test+Macro.swift

+14-16
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ public typealias __XCTestCompatibleSelector = Never
5353
/// - Parameters:
5454
/// - traits: Zero or more traits to apply to this test suite.
5555
///
56-
/// A test suite is a type that contains one or more test functions. Any
57-
/// copyable type (that is, any type that is not marked `~Copyable`) may be a
58-
/// test suite.
56+
/// A test suite is a type that contains one or more test functions. Any type
57+
/// may be a test suite.
5958
///
6059
/// The use of the `@Suite` attribute is optional; types are recognized as test
6160
/// suites even if they do not have the `@Suite` attribute applied to them.
@@ -81,9 +80,8 @@ public macro Suite(
8180
/// from the associated type's name.
8281
/// - traits: Zero or more traits to apply to this test suite.
8382
///
84-
/// A test suite is a type that contains one or more test functions. Any
85-
/// copyable type (that is, any type that is not marked `~Copyable`) may be a
86-
/// test suite.
83+
/// A test suite is a type that contains one or more test functions. Any type
84+
/// may be a test suite.
8785
///
8886
/// The use of the `@Suite` attribute is optional; types are recognized as test
8987
/// suites even if they do not have the `@Suite` attribute applied to them.
@@ -106,7 +104,7 @@ extension Test {
106104
/// - Warning: This function is used to implement the `@Suite` macro. Do not
107105
/// call it directly.
108106
public static func __type(
109-
_ containingType: any ~Copyable.Type,
107+
_ containingType: any (~Copyable & ~Escapable).Type,
110108
displayName: String? = nil,
111109
traits: [any SuiteTrait],
112110
sourceLocation: SourceLocation
@@ -159,7 +157,7 @@ extension Test {
159157
/// call it directly.
160158
public static func __function(
161159
named testFunctionName: String,
162-
in containingType: (any ~Copyable.Type)?,
160+
in containingType: (any (~Copyable & ~Escapable).Type)?,
163161
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
164162
displayName: String? = nil,
165163
traits: [any TestTrait],
@@ -241,7 +239,7 @@ extension Test {
241239
/// call it directly.
242240
public static func __function<C>(
243241
named testFunctionName: String,
244-
in containingType: (any ~Copyable.Type)?,
242+
in containingType: (any (~Copyable & ~Escapable).Type)?,
245243
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
246244
displayName: String? = nil,
247245
traits: [any TestTrait],
@@ -376,7 +374,7 @@ extension Test {
376374
/// call it directly.
377375
public static func __function<C1, C2>(
378376
named testFunctionName: String,
379-
in containingType: (any ~Copyable.Type)?,
377+
in containingType: (any (~Copyable & ~Escapable).Type)?,
380378
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
381379
displayName: String? = nil,
382380
traits: [any TestTrait],
@@ -404,7 +402,7 @@ extension Test {
404402
/// call it directly.
405403
public static func __function<C, E1, E2>(
406404
named testFunctionName: String,
407-
in containingType: (any ~Copyable.Type)?,
405+
in containingType: (any (~Copyable & ~Escapable).Type)?,
408406
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
409407
displayName: String? = nil,
410408
traits: [any TestTrait],
@@ -435,7 +433,7 @@ extension Test {
435433
/// call it directly.
436434
public static func __function<Key, Value>(
437435
named testFunctionName: String,
438-
in containingType: (any ~Copyable.Type)?,
436+
in containingType: (any (~Copyable & ~Escapable).Type)?,
439437
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
440438
displayName: String? = nil,
441439
traits: [any TestTrait],
@@ -460,7 +458,7 @@ extension Test {
460458
/// call it directly.
461459
public static func __function<C1, C2>(
462460
named testFunctionName: String,
463-
in containingType: (any ~Copyable.Type)?,
461+
in containingType: (any (~Copyable & ~Escapable).Type)?,
464462
xcTestCompatibleSelector: __XCTestCompatibleSelector?,
465463
displayName: String? = nil,
466464
traits: [any TestTrait],
@@ -524,7 +522,7 @@ extension Test {
524522
///
525523
/// - Warning: This function is used to implement the `@Test` macro. Do not use
526524
/// it directly.
527-
@inlinable public func __requiringTry<T>(_ value: consuming T) throws -> T where T: ~Copyable {
525+
@inlinable public func __requiringTry<T>(_ value: consuming T) throws -> T where T: ~Copyable & ~Escapable {
528526
value
529527
}
530528

@@ -533,7 +531,7 @@ extension Test {
533531
///
534532
/// - Warning: This function is used to implement the `@Test` macro. Do not use
535533
/// it directly.
536-
@inlinable public func __requiringAwait<T>(_ value: consuming T, isolation: isolated (any Actor)? = #isolation) async -> T where T: ~Copyable {
534+
@inlinable public func __requiringAwait<T>(_ value: consuming T, isolation: isolated (any Actor)? = #isolation) async -> T where T: ~Copyable & ~Escapable {
537535
value
538536
}
539537

@@ -556,7 +554,7 @@ public var __defaultSynchronousIsolationContext: (any Actor)? {
556554
_ selector: __XCTestCompatibleSelector?,
557555
onInstanceOf type: T.Type,
558556
sourceLocation: SourceLocation
559-
) async throws -> Bool where T: ~Copyable {
557+
) async throws -> Bool where T: ~Copyable & ~Escapable {
560558
false
561559
}
562560

Tests/TestingTests/CustomTestStringConvertibleTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct CustomTestStringConvertibleTests {
5454

5555
// MARK: - Fixtures
5656

57-
private struct NonCopyableType: ~Copyable {}
57+
private struct NonCopyableType: ~Copyable, ~Escapable {}
5858

5959
private struct CustomStringConvertibleType: CustomStringConvertible {
6060
var description: String {

Tests/TestingTests/NonCopyableSuiteTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@testable @_spi(ForToolsIntegrationOnly) import Testing
1212

1313
@Suite("Non-Copyable Tests")
14-
struct NonCopyableTests: ~Copyable {
14+
struct NonCopyableTests: ~Copyable, ~Escapable {
1515
@Test static func staticMe() {}
1616
@Test borrowing func borrowMe() {}
1717
@Test consuming func consumeMe() {}

cmake/modules/shared/CompilerSettings.cmake

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ add_compile_options(
1414
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -require-explicit-sendable>")
1515
add_compile_options(
1616
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-experimental-feature -Xfrontend AccessLevelOnImport>"
17-
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-experimental-feature -Xfrontend SuppressedAssociatedTypes>")
17+
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-experimental-feature -Xfrontend SuppressedAssociatedTypes>"
18+
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-experimental-feature -Xfrontend LifetimeDependence>")
1819
add_compile_options(
1920
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-upcoming-feature -Xfrontend ExistentialAny>"
2021
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-upcoming-feature -Xfrontend InternalImportsByDefault>")

0 commit comments

Comments
 (0)