Skip to content

Add a reserved argument to the test content record accessor signature. #1017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions Documentation/ABI/TestContent.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ testing library have the following layout:
typealias Accessor = @convention(c) (
_ outValue: UnsafeMutableRawPointer,
_ type: UnsafeRawPointer,
_ hint: UnsafeRawPointer?
_ hint: UnsafeRawPointer?,
_ reserved: UInt
) -> CBool

typealias TestContentRecord = (
Expand All @@ -63,7 +64,8 @@ If needed, this type can be represented in C as a structure:
typedef bool (* SWTAccessor)(
void *outValue,
const void *type,
const void *_Nullable hint
const void *_Nullable hint,
uintptr_t reserved
);

struct SWTTestContentRecord {
Expand Down Expand Up @@ -117,7 +119,7 @@ If `accessor` is `nil`, the test content record is ignored. The testing library
may, in the future, define record kinds that do not provide an accessor function
(that is, they represent pure compile-time information only.)

The third argument to this function, `type`, is a pointer to the type[^mightNotBeSwift]
The second argument to this function, `type`, is a pointer to the type[^mightNotBeSwift]
(not a bitcast Swift type) of the value expected to be written to `outValue`.
This argument helps to prevent memory corruption if two copies of Swift Testing
or a third-party library are inadvertently loaded into the same process. If the
Expand All @@ -134,12 +136,15 @@ accessor function must return `false` and must not modify `outValue`.
[`std::type_info`](https://en.cppreference.com/w/cpp/types/type_info), and
write a C++ class instance to `outValue` using [placement `new`](https://en.cppreference.com/w/cpp/language/new#Placement_new).

The fourth argument to this function, `hint`, is an optional input that can be
The third argument to this function, `hint`, is an optional input that can be
passed to help the accessor function determine if its corresponding test content
record matches what the caller is looking for. If the caller passes `nil` as the
`hint` argument, the accessor behaves as if it matched (that is, no additional
filtering is performed.)

The fourth argument to this function, `reserved`, is reserved for future use.
Accessor functions should assume it is `0` and must not access it.

The concrete Swift type of the value written to `outValue`, the type pointed to
by `type`, and the value pointed to by `hint` depend on the kind of record:

Expand Down
3 changes: 2 additions & 1 deletion Sources/Testing/Discovery+Macro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ protocol DiscoverableAsTestContent: _TestDiscovery.DiscoverableAsTestContent, ~C
public typealias __TestContentRecordAccessor = @convention(c) (
_ outValue: UnsafeMutableRawPointer,
_ type: UnsafeRawPointer,
_ hint: UnsafeRawPointer?
_ hint: UnsafeRawPointer?,
_ reserved: UInt
) -> CBool

/// The content of a test content record.
Expand Down
2 changes: 1 addition & 1 deletion Sources/TestingMacros/ConditionMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ extension ExitTestConditionMacro {
"""
@available(*, deprecated, message: "This type is an implementation detail of the testing library. Do not use it directly.")
enum \(enumName) {
private nonisolated static let accessor: Testing.__TestContentRecordAccessor = { outValue, type, hint in
private nonisolated static let accessor: Testing.__TestContentRecordAccessor = { outValue, type, hint, _ in
Testing.ExitTest.__store(
\(exitTestIDExpr),
\(bodyThunkName),
Expand Down
2 changes: 1 addition & 1 deletion Sources/TestingMacros/SuiteDeclarationMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public struct SuiteDeclarationMacro: MemberMacro, PeerMacro, Sendable {
result.append(
"""
@available(*, deprecated, message: "This property is an implementation detail of the testing library. Do not use it directly.")
private nonisolated static let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _ in
private nonisolated static let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _, _ in
Testing.Test.__store(\(generatorName), into: outValue, asTypeAt: type)
}
"""
Expand Down
2 changes: 1 addition & 1 deletion Sources/TestingMacros/TestDeclarationMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
result.append(
"""
@available(*, deprecated, message: "This property is an implementation detail of the testing library. Do not use it directly.")
private \(staticKeyword(for: typeName)) nonisolated let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _ in
private \(staticKeyword(for: typeName)) nonisolated let \(accessorName): Testing.__TestContentRecordAccessor = { outValue, type, _, _ in
Testing.Test.__store(\(generatorName), into: outValue, asTypeAt: type)
}
"""
Expand Down
7 changes: 4 additions & 3 deletions Sources/_TestDiscovery/TestContentRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
private typealias _TestContentRecordAccessor = @convention(c) (
_ outValue: UnsafeMutableRawPointer,
_ type: UnsafeRawPointer,
_ hint: UnsafeRawPointer?
_ hint: UnsafeRawPointer?,
_ reserved: UInt
) -> CBool

/// The content of a test content record.
Expand Down Expand Up @@ -160,10 +161,10 @@ public struct TestContentRecord<T> where T: DiscoverableAsTestContent & ~Copyabl
withUnsafeTemporaryAllocation(of: T.self, capacity: 1) { buffer in
let initialized = if let hint {
withUnsafePointer(to: hint) { hint in
accessor(buffer.baseAddress!, type, hint)
accessor(buffer.baseAddress!, type, hint, 0)
}
} else {
accessor(buffer.baseAddress!, type, nil)
accessor(buffer.baseAddress!, type, nil, 0)
}
guard initialized else {
return nil
Expand Down
2 changes: 1 addition & 1 deletion Tests/TestingTests/DiscoveryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ struct DiscoveryTests {
private static let record: __TestContentRecord = (
0xABCD1234,
0,
{ outValue, type, hint in
{ outValue, type, hint, _ in
guard type.load(as: Any.Type.self) == MyTestContent.self else {
return false
}
Expand Down