Skip to content
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
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ extension Array where Element == PackageDescription.SwiftSetting {
.enableExperimentalFeature("AvailabilityMacro=_regexAPI:macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0"),
.enableExperimentalFeature("AvailabilityMacro=_swiftVersionAPI:macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0"),
.enableExperimentalFeature("AvailabilityMacro=_typedThrowsAPI:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"),
.enableExperimentalFeature("AvailabilityMacro=_castingWithNonCopyableGenerics:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"),

.enableExperimentalFeature("AvailabilityMacro=_distantFuture:macOS 99.0, iOS 99.0, watchOS 99.0, tvOS 99.0, visionOS 99.0"),
]
Expand Down
16 changes: 6 additions & 10 deletions Sources/Testing/Attachments/Attachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,17 @@ public struct AnyAttachable: AttachableWrapper, Sendable, Copyable {

// MARK: - Describing an attachment

extension Attachment where AttachableValue: ~Copyable {
@_documentation(visibility: private)
public var description: String {
let typeInfo = TypeInfo(describing: AttachableValue.self)
return #""\#(preferredName)": instance of '\#(typeInfo.unqualifiedName)'"#
}
}

extension Attachment: CustomStringConvertible {
extension Attachment: CustomStringConvertible where AttachableValue: ~Copyable {
/// @Metadata {
/// @Available(Swift, introduced: 6.2)
/// @Available(Xcode, introduced: 26.0)
/// }
public var description: String {
#""\#(preferredName)": \#(String(describingForTest: attachableValue))"#
if #available(_castingWithNonCopyableGenerics, *), let attachableValue = boxCopyableValue(attachableValue) {
return #""\#(preferredName)": \#(String(describingForTest: attachableValue))"#
}
let typeInfo = TypeInfo(describing: AttachableValue.self)
return #""\#(preferredName)": instance of '\#(typeInfo.unqualifiedName)'"#
}
}

Expand Down
1 change: 1 addition & 0 deletions Sources/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ add_library(Testing
Support/Additions/ArrayAdditions.swift
Support/Additions/CollectionDifferenceAdditions.swift
Support/Additions/CommandLineAdditions.swift
Support/Additions/CopyableAdditions.swift
Support/Additions/NumericAdditions.swift
Support/Additions/ResultAdditions.swift
Support/Additions/TaskAdditions.swift
Expand Down
47 changes: 47 additions & 0 deletions Sources/Testing/Support/Additions/CopyableAdditions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if !hasFeature(Embedded)
/// A helper protocol for ``boxCopyableValue(_:)``.
private protocol _CopyablePointer {
/// Load the value at this address into an existential box.
///
/// - Returns: The value at this address.
func load() -> Any
}

extension UnsafePointer: _CopyablePointer where Pointee: Copyable {
func load() -> Any {
pointee
}
}
#endif

/// Copy a value to an existential box if its type conforms to `Copyable`.
///
/// - Parameters:
/// - value: The value to copy.
///
/// - Returns: A copy of `value` in an existential box, or `nil` if the type of
/// `value` does not conform to `Copyable`.
///
/// When using Embedded Swift, this function always returns `nil`.
#if !hasFeature(Embedded)
@available(_castingWithNonCopyableGenerics, *)
func boxCopyableValue(_ value: borrowing some ~Copyable) -> Any? {
withUnsafePointer(to: value) { address in
return (address as? any _CopyablePointer)?.load()
}
}
#else
func boxCopyableValue(_ value: borrowing some ~Copyable) -> Void? {
nil
}
#endif
1 change: 1 addition & 0 deletions cmake/modules/shared/AvailabilityDefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ add_compile_options(
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -define-availability -Xfrontend \"_regexAPI:macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0\">"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -define-availability -Xfrontend \"_swiftVersionAPI:macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0\">"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -define-availability -Xfrontend \"_typedThrowsAPI:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0\">"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -define-availability -Xfrontend \"_castingWithNonCopyableGenerics:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0\">"
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -define-availability -Xfrontend \"_distantFuture:macOS 99.0, iOS 99.0, watchOS 99.0, tvOS 99.0, visionOS 99.0\">")