Skip to content

Commit f1d5488

Browse files
authored
[Proposal] AttributedString & SendableMetatype (#1408)
* [Proposal] AttributedString & SendableMetatype * Assign SF-0029, update status/link to review
1 parent 03524db commit f1d5488

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# `AttributedString` & `SendableMetatype`
2+
3+
* Proposal: [SF-0029](0029-attributedstring-sendable-metatype.md)
4+
* Authors: [Jeremy Schonfeld](https://github.com/jmschonfeld)
5+
* Review Manager: [Tina L](https://github.com/itingliu)
6+
* Status: **Review: July 22...July 29, 2025**
7+
* Review: [Pitch](https://forums.swift.org/t/pitch-attributedstring-sendablemetatype/80986)
8+
9+
10+
11+
## Introduction/Motivation
12+
13+
[SE-0470 Global-actor isolated conformances](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0470-isolated-conformances.md) introduced the concept of a conformance isolated to a global actor. This in turn introduced the ability for metatypes to be non-`Sendable` as a generic metatype's conformance to a protocol may be isolated to a global actor. Since metatypes are not guaranteed to be `Sendable`, generic functions that pass metatypes across isolation boundaries now need to specify that they require `Sendable` metatypes (i.e. the conformance to the specified protocol must be nonisolated). One common API in Foundation that needs to pass metatypes across actor isolations is `AttributedString` via its `AttributedStringKey` and `AttributeScope` protocols. `AttributedString` contains a variety of APIs that accept generic metatypes constrained to these protocols. In many cases, these metatypes need to be passed across actor isolations (such as storing the contents of a scope in a cache, storing attribute keys in `Sendable` `AttributedString`s and related types, etc.). We need to update Foundation's APIs to ensure that these assumptions around `Sendable` `AttributedStringKey` and `AttributeScope` metatypes still hold.
14+
15+
## Proposed solution and example
16+
17+
Since Foundation needs to pass these metatypes across isolation boundaries and there is no benefit to providing an isolated conformance to `AttributeScope`/`AttributedStringKey` as the types themselves should never access global state and are never initialized, I propose annotating `AttributedStringKey` and `AttributeScope` as conforming to `SendableMetatype` to prevent isolated conformances to these protocols. Developers that do not bind their keys/scopes to global actors will see no impact, but developers that declare isolated conformances to either of these protocols will now see a compilation warning/error:
18+
19+
```swift
20+
struct MyAttributeKey : @MainActor AttributedStringKey {
21+
typealias Value = Int
22+
static let name = "MyFramework.MyAttributeKey"
23+
}
24+
25+
var myString = AttributedString()
26+
myString[MyAttributeKey.self] = 2 // Main actor-isolated conformance of 'MyAttributeKey' to 'AttributedStringKey' cannot satisfy conformance requirement for a 'Sendable' type parameter
27+
```
28+
29+
## Detailed design
30+
31+
The `SendableMetatype` conformance will be added to the pre-existing `AttributedStringKey` and `AttributeScope` protocols:
32+
33+
```swift
34+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
35+
public protocol AttributedStringKey : SendableMetatype {
36+
// ...
37+
}
38+
39+
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
40+
public protocol AttributeScope : DecodingConfigurationProviding, EncodingConfigurationProviding, SendableMetatype {
41+
// ...
42+
}
43+
```
44+
45+
## Source compatibility
46+
47+
Isolated conformances are new to Swift 6.2 and therefore all existing code (which must use nonisolated conformances) will not be impacted. Any code that has already adopted an isolated conformance here in Swift 6.2 will now see a warning (or error in Swift 6 mode) when providing these key/scope types to `AttributedString` APIs.
48+
49+
Since `SendableMetatype` is a marker protocol, this change does not impact ABI and does not require availability adjustments.
50+
51+
## Implications on adoption
52+
53+
Modules that define conformances to `AttributedStringKey` or `AttributeScope` will not be able to define them as isolated conformances. The conformances must be nonisolated.
54+
55+
## Future directions
56+
57+
None.
58+
59+
## Alternatives considered
60+
61+
### Adding a `SendableMetatype` annotation to all applicable `AttributedString` APIs
62+
63+
Instead, we could add the conformance to every `AttributedString` API that accepts a key or scope in case these keys/scope types are used in other APIs that do not require a nonisolated conformance. I chose to not pursue this route as it required more complex changes, it has mostly the same effect, and I don't expect any client to realistically require an isolated conformance to these protocols.

0 commit comments

Comments
 (0)