@@ -24,15 +24,29 @@ public struct ExitTest: Sendable, ~Copyable {
2424 /// The expected exit condition of the exit test.
2525 public var expectedExitCondition : ExitCondition
2626
27- /// The body closure of the exit test.
28- fileprivate var body : @Sendable ( ) async throws -> Void = { }
29-
3027 /// The source location of the exit test.
3128 ///
3229 /// The source location is unique to each exit test and is consistent between
3330 /// processes, so it can be used to uniquely identify an exit test at runtime.
3431 public var sourceLocation : SourceLocation
3532
33+ /// The body closure of the exit test.
34+ fileprivate var body : @Sendable ( ) async throws -> Void
35+
36+ /// Initialize an exit test at runtime.
37+ ///
38+ /// - Warning: This initializer is used to implement the `#expect(exitsWith:)`
39+ /// macro. Do not use it directly.
40+ public init (
41+ __expectedExitCondition expectedExitCondition: ExitCondition ,
42+ sourceLocation: SourceLocation ,
43+ body: @escaping @Sendable ( ) async throws -> Void = { }
44+ ) {
45+ self . expectedExitCondition = expectedExitCondition
46+ self . sourceLocation = sourceLocation
47+ self . body = body
48+ }
49+
3650 /// Disable crash reporting, crash logging, or core dumps for the current
3751 /// process.
3852 private static func _disableCrashReporting( ) {
@@ -102,44 +116,24 @@ public struct ExitTest: Sendable, ~Copyable {
102116
103117// MARK: - Discovery
104118
105- /// A protocol describing a type that contains an exit test.
106- ///
107- /// - Warning: This protocol is used to implement the `#expect(exitsWith:)`
108- /// macro. Do not use it directly.
109- @_alwaysEmitConformanceMetadata
110- @_spi ( Experimental)
111- public protocol __ExitTestContainer {
112- /// The expected exit condition of the exit test.
113- static var __expectedExitCondition : ExitCondition { get }
114-
115- /// The source location of the exit test.
116- static var __sourceLocation : SourceLocation { get }
117-
118- /// The body function of the exit test.
119- static var __body : @Sendable ( ) async throws -> Void { get }
120- }
121-
122119extension ExitTest {
123- /// A string that appears within all auto-generated types conforming to the
124- /// `__ExitTestContainer` protocol.
125- private static let _exitTestContainerTypeNameMagic = " __🟠$exit_test_body__ "
126-
127120 /// Find the exit test function at the given source location.
128121 ///
129122 /// - Parameters:
130123 /// - sourceLocation: The source location of the exit test to find.
131124 ///
132125 /// - Returns: The specified exit test function, or `nil` if no such exit test
133126 /// could be found.
127+ @_spi ( ForToolsIntegrationOnly)
134128 public static func find( at sourceLocation: SourceLocation ) -> Self ? {
135129 var result : Self ?
136130
137- enumerateTypes ( withNamesContaining : _exitTestContainerTypeNameMagic ) { _, type , stop in
138- if let type = type as? any __ExitTestContainer . Type , type . __sourceLocation == sourceLocation {
131+ enumerateTestContent ( ofKind : . exitTest , as : ExitTest . self ) { _, exitTest , _ , stop in
132+ if exitTest . sourceLocation == sourceLocation {
139133 result = ExitTest (
140- expectedExitCondition : type . __expectedExitCondition ,
141- body : type . __body ,
142- sourceLocation : type . __sourceLocation
134+ __expectedExitCondition : exitTest . expectedExitCondition ,
135+ sourceLocation : exitTest . sourceLocation ,
136+ body : exitTest . body
143137 )
144138 stop = true
145139 }
@@ -183,7 +177,7 @@ func callExitTest(
183177
184178 let actualExitCondition : ExitCondition
185179 do {
186- let exitTest = ExitTest ( expectedExitCondition : expectedExitCondition, sourceLocation: sourceLocation)
180+ let exitTest = ExitTest ( __expectedExitCondition : expectedExitCondition, sourceLocation: sourceLocation)
187181 actualExitCondition = try await configuration. exitTestHandler ( exitTest)
188182 } catch {
189183 // An error here would indicate a problem in the exit test handler such as a
@@ -295,7 +289,7 @@ extension ExitTest {
295289 // External tools authors should set up their own back channel mechanisms
296290 // and ensure they're installed before calling ExitTest.callAsFunction().
297291 guard var result = find ( at: sourceLocation) else {
298- return nil
292+ fatalError ( " Could not find an exit test that should have been located at \( sourceLocation ) . " )
299293 }
300294
301295 // We can't say guard let here because it counts as a consume.
0 commit comments