この記事の要点
- Swift 5.6 が正式リリースされました。型システムの拡張、ポインタとの相互運用の改善、そして Swift Package Manager のプラグイン機能の追加が中心です。
- 型システムでは、type placeholder(型の一部だけ
_で省略する)と、existential 型を明示するanyキーワードが導入されました。 - ポインタ関連では、一時的な未初期化バッファ、C 関数へのポインタ引数の診断緩和、unsafe ポインタ型からの
Sendable適合の削除という 3 つの改善が入りました。 - 並行処理では、concurrency チェックへの段階的な移行(
Sendable関連の診断を-warn-concurrencyなどで必要に応じて有効化)がサポートされました。これは Swift 5.5 で導入された並行処理機能から本格的なデータ競合安全性へ移行するための布石です。 - Swift Package Manager に build tool plugin と command plugin が加わり、ビルド中のコード生成やパッケージへのカスタムコマンドを定義できるようになりました。Swift-DocC もこのプラグイン機構を使った SwiftPM プラグインとして利用できるようになりました。
主な変更点
型システムの拡張
type placeholder(SE-0315)
型推論で省略できる部分は省略しつつ、明示が必要な部分だけを書きたい場合があります。type placeholder は、型注釈の一部を _ で書き、その部分の型をコンパイラに推論させる機能です。
enum Either<Left, Right> {
case left(Left)
case right(Right)
}
// Either<ClosedRange<Int>, Range<Int>> と推論される
let either: Either<_, Range<Int>> = .left(0...10)
型全体を書かずに、明確さのために必要な部分(ここでは Range<Int>)だけを指定できます。
existential any(SE-0335)
existential 型は、特定のプロトコルに適合する任意の型の値を保持するための型です。Swift 5.6 までは、existential 型はプロトコル名(やプロトコル合成)をそのまま書く構文でした。
protocol DataSourceObserver { ... }
struct DataSource {
var observers: [DataSourceObserver] { ... }
}
existential 型は元の型情報を消去するため、動的に型を切り替えられる一方で、プロトコルへの適合などはできないといった制約があります。しかし、従来の構文では existential 型がジェネリックの適合要件と見分けがつかず、この違いが分かりにくいという問題がありました。
Swift 5.6 では、existential 型を any キーワードで明示できるようになりました。
protocol DataSourceObserver { ... }
struct DataSource {
var observers: [any DataSourceObserver] { ... }
}
Swift 5.6 時点では any は任意ですが、existential 型を使っていることがコード上で明確になります。
ポインタとの相互運用の改善
- 一時的な未初期化バッファ(SE-0322): 一時的な未初期化のメモリ領域を確保する新しい仕組みです。計算結果を書き込むためのメモリを渡す必要がある C API との連携で特に役立ちます。
- C 関数へのポインタ引数の診断緩和(SE-0324): イミュータブルなポインタ(
UnsafePointerなど)を受け取る API に、対応するミュータブルなポインタ(UnsafeMutablePointerなど)を、明示的な変換なしで渡せるようになりました。 - unsafe ポインタ型からの
Sendable適合の削除(SE-0331): unsafe ポインタ型は参照のように振る舞うため、そのSendable適合(特に暗黙の適合)が予期しない問題を招くことが分かりました。そこで unsafe ポインタ型からSendable適合が削除されました。
concurrency チェックへの段階的な移行(SE-0337)
Swift 5.6 では、Sendable に関する診断はデフォルトでは抑制されています。Sendable への適合を明示的に書くか、-warn-concurrency コンパイラフラグを使うことで診断を有効にでき、concurrency チェックへ段階的に移行できます。これにより、既存コードを一度にすべて対応させなくても、少しずつデータ競合安全性に近づけられます。
Swift Package Manager のプラグイン
Swift 5.6 で Swift Package Manager に拡張性のための機能が加わり、あわせてセキュリティ・性能・信頼性の重要なアップデートも入りました。
build tool plugin(SE-0303)
ビルド中に自動的に呼び出されるカスタムツールを、プラグインとして定義できるようになりました。.proto ファイルなどの入力から Swift のソースファイルを生成する、といったビルド中のコード生成を主な用途とします。ビルドグラフに組み込まれ、安全な形で自動実行されます。
command plugin(SE-0332)
SE-0303 で導入されたプラグインの仕組みを拡張し、ユーザーが SwiftPM の CLI や対応 IDE から直接呼び出せるカスタムコマンドを定義できるようになりました。コマンドには「ドキュメント生成」「ソースコードの整形」といった定義済みの意図か、独自の動詞(swift package <verb>)を指定できます。
その他の SwiftPM の更新
- binary target の改善(SE-0305)。
- メジャー・マイナーだけの Git タグ(
X.Y形式)をX.Y.0として扱えるようになり、既存リポジトリとの互換性が向上しました。 - セキュリティ向上のため、初回利用時に信頼する TOFU(trust on first use)検証を行います。Git リポジトリから初めてパッケージを取得した時点でフィンガープリントを記録し、以降のダウンロードで一致しない場合は設定に応じて警告またはビルド失敗になります。
- 依存解決インフラの改善により、性能と信頼性が向上しました。
Swift-DocC のアップデート
- Swift-DocC が、新しいプラグインコマンド機構を使った SwiftPM プラグイン として利用できるようになりました。
- Swift-DocC で GitHub Pages への静的コンテンツの公開ができるようになりました。
doccコマンドラインツールが、macOS・Linux 向けのオープンソースなリリース版ツールチェインに含まれるようになりました。- コマンドラインツールやアプリなどの実行可能ターゲットのドキュメントも生成できるようになりました。
Swift 利用者への影響
- 型注釈を必要な部分だけ書けます。 type placeholder により、型の一部を
_で省略して、明確さのために必要な部分だけを明示できます。 - existential を明示できます。
anyキーワードにより existential 型であることをコード上で示せます。今後のリリースで existential 型をより安全に扱うための土台になります。 - C API との連携が楽になります。 一時的な未初期化バッファや、ミュータブルポインタの暗黙変換により、C API へポインタを渡すコードが書きやすくなりました。
- データ競合安全性へ段階的に移行できます。
-warn-concurrencyなどでSendable関連の診断を必要に応じて有効化し、既存コードを少しずつ並行処理チェックに対応させられます。 - ビルドを拡張できます。 SwiftPM の build tool plugin と command plugin により、ビルド中のコード生成やパッケージへのカスタムコマンドを定義でき、Swift-DocC のドキュメント生成もプラグインとして組み込めます。
関連リンク
- 前のリリースについては Swift 5.5 リリース を参照してください。
- 本記事で触れた Proposal ダイジェスト:
- Swift のダウンロード
- The Swift Programming Language