Swift Digest

AttributedStringSendableMetatype

AttributedString & SendableMetatype

Proposal
SF-0029
Authors
Jeremy Schonfeld
Review Manager
Tina L
Status
Review: July 22...July 29, 2025

このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら

01 何が問題だったのか

SE-0470 によって、プロトコルへの適合をグローバルアクターに isolate する isolated conformance が導入されました。これに伴い、ジェネリックなメタタイプ(T.Type)はグローバルアクターに isolate された適合を介して状態にアクセスし得るため、メタタイプはもはや一律に Sendable ではなくなりました。isolation boundary を越えてメタタイプを受け渡すジェネリック関数は、型パラメータに SendableMetatype 制約を付けて、適合が nonisolated であることを要求しなければなりません。

Foundation の AttributedString は、こうした「メタタイプを isolation boundary を越えて受け渡す」典型的な API です。AttributedString のさまざまな API は、AttributedStringKeyAttributeScope プロトコルに制約された型パラメータでジェネリックメタタイプを受け取り、scope の内容をキャッシュしたり、SendableAttributedString の中に attribute key を保持したりします。

AttributedStringKeyAttributeScope への適合がグローバルアクターに isolate されてしまうと、これらの API はメタタイプを isolation boundary を越えて運べなくなり、AttributedString のデータ競合安全性が崩れてしまいます。一方で、AttributedStringKeyAttributeScope に適合する型はグローバル状態にアクセスする必要も初期化される必要もなく、isolated conformance を許す利点はそもそもありません。

02 どのように解決されるのか

AttributedStringKeyAttributeScope の両プロトコルが SendableMetatype を継承するように変更されます。これにより、これらのプロトコルへの isolated conformance は禁止され、AttributedString の API がメタタイプを isolation boundary を越えて安全に受け渡せることが保証されます。

@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
public protocol AttributedStringKey: SendableMetatype {
    // ...
}

@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
public protocol AttributeScope: DecodingConfigurationProviding, EncodingConfigurationProviding, SendableMetatype {
    // ...
}

SendableMetatype はマーカープロトコルなので、ABI への影響はなく、availability の調整も不要です。

これまでどおり nonisolated に適合させているコードには影響はありません。一方で、key や scope の適合をグローバルアクターに isolate していたコードは、AttributedString の API へ渡すときに診断が出るようになります。

struct MyAttributeKey: @MainActor AttributedStringKey {
    typealias Value = Int
    static let name = "MyFramework.MyAttributeKey"
}

var myString = AttributedString()
myString[MyAttributeKey.self] = 2
// error: Main actor-isolated conformance of 'MyAttributeKey' to 'AttributedStringKey'
// cannot satisfy conformance requirement for a 'Sendable' type parameter

isolated conformance は Swift 6.2 で導入された機能のため、Swift 6.2 より前のコードはすべて nonisolated な適合となっており、今回の変更による影響はありません。Swift 6.2 ですでに isolated conformance を採用していたコードでは、Swift 6 モードでエラー、それ以外では警告が出るようになります。対処としては、AttributedStringKeyAttributeScope への適合からグローバルアクター属性を外し、nonisolated な適合に戻します。