Skip to content

Commit 33e3787

Browse files
authored
Modify boxCopyableValue(_:) to take ~Escapable values too. (#1518)
This PR changes `boxCopyableValue(_:)` into `makeExistential(_:)` which can take values of types with suppressed conformances to `~Escapable`, not just `~Copyable`. The change also gets us away from using `UnsafePointer` as a helper type (this use of `UnsafePointer` isn't inherently unsafe, but still, the fewer pointers the better.) ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent 1f2893c commit 33e3787

2 files changed

Lines changed: 26 additions & 15 deletions

File tree

Sources/Testing/Attachments/Attachment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ extension Attachment: CustomStringConvertible where AttachableValue: ~Copyable {
173173
/// @Available(Xcode, introduced: 26.0)
174174
/// }
175175
public var description: String {
176-
if #available(_castingWithNonCopyableGenerics, *), let attachableValue = boxCopyableValue(attachableValue) {
176+
if #available(_castingWithNonCopyableGenerics, *), let attachableValue = makeExistential(attachableValue) {
177177
return #""\#(preferredName)": \#(String(describingForTest: attachableValue))"#
178178
}
179179
let typeInfo = TypeInfo(describing: AttachableValue.self)
Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,40 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2025 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2025–2026 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
88
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
99
//
1010

1111
#if !hasFeature(Embedded)
12-
/// A helper protocol for ``boxCopyableValue(_:)``.
13-
private protocol _CopyablePointer {
14-
/// Load the value at this address into an existential box.
12+
/// A helper protocol for ``makeExistential(_:)``.
13+
private protocol _CopierProtocol<Referent> {
14+
/// The type of value that a conforming type can copy.
15+
associatedtype Referent
16+
17+
/// Cast the given value to `Any`.
18+
///
19+
/// - Parameters:
20+
/// - value: The value to cast.
1521
///
16-
/// - Returns: The value at this address.
17-
func load() -> Any
22+
/// - Returns: `value` cast to `Any`.
23+
static func cast(_ value: Referent) -> Any
1824
}
1925

20-
extension UnsafePointer: _CopyablePointer where Pointee: Copyable {
21-
func load() -> Any {
22-
pointee
26+
/// A helper type for ``makeExistential(_:)``
27+
private struct _Copier<Referent> where Referent: ~Copyable & ~Escapable {}
28+
29+
extension _Copier: _CopierProtocol where Referent: Copyable & Escapable {
30+
static func cast(_ value: Referent) -> Any {
31+
value
2332
}
2433
}
2534
#endif
2635

27-
/// Copy a value to an existential box if its type conforms to `Copyable`.
36+
/// Copy a value to an existential box if its type conforms to `Copyable` and
37+
/// `Escapable`.
2838
///
2939
/// - Parameters:
3040
/// - value: The value to copy.
@@ -35,13 +45,14 @@ extension UnsafePointer: _CopyablePointer where Pointee: Copyable {
3545
/// When using Embedded Swift, this function always returns `nil`.
3646
#if !hasFeature(Embedded)
3747
@available(_castingWithNonCopyableGenerics, *)
38-
func boxCopyableValue(_ value: borrowing some ~Copyable) -> Any? {
39-
withUnsafePointer(to: value) { address in
40-
return (address as? any _CopyablePointer)?.load()
48+
func makeExistential<T>(_ value: borrowing T) -> Any? where T: ~Copyable & ~Escapable {
49+
if let type = _Copier<T>.self as? any _CopierProtocol<T>.Type {
50+
return type.cast(value)
4151
}
52+
return nil
4253
}
4354
#else
44-
func boxCopyableValue(_ value: borrowing some ~Copyable) -> Void? {
55+
func makeExistential<T>(_ value: borrowing T) -> Void? where T: ~Copyable & ~Escapable {
4556
nil
4657
}
4758
#endif

0 commit comments

Comments
 (0)