Skip to content

Commit 1db8e6e

Browse files
committed
Proposal to generalize closure-based functions for Data
1 parent 8eb80f2 commit 1db8e6e

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Generalize closure-based functions of `Data`
2+
3+
* Proposal: [SF-NNNN](nnnn-generalize-closure-based-functions-in-Data.md)
4+
* Authors: [Guillaume Lessard](https://github.com/glessard)
5+
* Review Manager: TBD
6+
* Status: **Awaiting implementation** or **Awaiting review**
7+
* Bug: *if applicable* [swiftlang/swift-foundation#1638](https://github.com/swiftlang/swift-foundation/issues/1638)
8+
9+
Implementation: [swiftlang/swift-foundation#1622](https://github.com/swiftlang/swift-foundation/pull/1622)
10+
11+
* Review: ([pitch](https://forums.swift.org/...))
12+
13+
## Introduction
14+
15+
We propose to generalize the closure-taking API of `Data` for typed throws and for noncopyable return values, making them able to accept a greater variety of closures.
16+
17+
## Motivation
18+
19+
Since [SE-0427], noncopyable types can participate in Swift generics, but `Data` has not been adapted to allow working with noncopyable values. [SE-0437] paved the way by generalizing low-level constructs such as `UnsafeBufferPointer<T>`, and as a result the community of Swift systems programmers now expects that generic functions such as `withUnsafeBytes()` can return noncopyable values.
20+
21+
In [SE-0413], we also added the ability for functions to throw typed errors. This ability is important in high-performance contexts such as embedded Swift, and functions such as `withUnsafeBytes()` should support closures with typed errors.
22+
23+
`Data`'s current closure-based functions such as `withUnsafeBytes()` cannot take advantage of either of these newer features:
24+
25+
```swift
26+
extension Data {
27+
public func withUnsafeBytes<ResultType>(
28+
_ apply: (UnsafeRawBufferPointer) throws -> ResultType
29+
) rethrows -> ResultType
30+
}
31+
```
32+
33+
34+
35+
## Proposed solution
36+
37+
We will add support for typed throws and noncopyable return values to the functions of `Data` that take closure arguments with generic types.
38+
39+
## Detailed design
40+
41+
The signatures of `Data`'s three closure-based functions will become:
42+
43+
```swift
44+
extension Data {
45+
public func withUnsafeBytes<E: Error, ResultType: ~Copyable>(
46+
_ apply: (UnsafeRawBufferPointer) throws(E) -> ResultType
47+
) throws(E) -> ResultType
48+
49+
public func withContiguousStorageIfAvailable<E: Error, ResultType: ~Copyable>(
50+
_ body: (_ buffer: UnsafeBufferPointer<UInt8>) throws(E) -> ResultType
51+
) throws(E) -> ResultType?
52+
53+
public mutating func withUnsafeMutableBytes<E: Error, ResultType: ~Copyable>(
54+
_ body: (UnsafeMutableRawBufferPointer) throws(E) -> ResultType
55+
) throws(E) -> ResultType
56+
}
57+
```
58+
59+
These are new functions that replace existing functions in a source-compatible way. The older signature required `ResultType` type to be `Copyable`, allowing it to also satisfy the `~Copyable` constraint. The untyped errors thrown by existing closures are a special case of the typed error case, where `E == any Error`.
60+
61+
## Source compatibility
62+
63+
This change is source-compatible with existing call sites.
64+
65+
## Implications on adoption
66+
67+
On ABI-stable platforms, the existing ABI will be preserved. The new entry points will be declared `@_alwaysEmitIntoClient` in order to help the compiler specialize use sites in practice.
68+
69+
## Alternatives considered
70+
71+
(none)
72+

0 commit comments

Comments
 (0)