AppleのSwiftチームがWWDC26のラボで語ったこと
AppleはWWDC26 Swift Group Labを、Swift、Foundation、サーバーネットワーキングの各チームのエンジニア4名による1時間の台本なしのQ&Aとして公開し、しかも字幕を付けずに出しました。1 彼らが実際に何を語ったのかを読むために、この動画をローカルで文字起こしにかけました。洗練されたセッションは、機能が「何をするか」を教えてくれます。一方ラボは、Hollyが並行処理の核心的な設計判断について自分が間違っていたと認める場面であり、Coreyがキャンセルされたコードのなかで静かに失敗するクリーンアップのパターンを説明する場面であり、そしてパネルがマーケティングでは決して口にしないひとつの助言を繰り返す場面です。それは「言語機能を集めるのをやめなさい」というもの。率直な姿はここにあります。
出典についての注記:Appleはこのラボの公式トランスクリプトを公開していません。以下の引用はすべて、公開された動画をローカルで文字起こししたものからのパラフレーズであり、タイムスタンプはおおよそのものです。話者はトランスクリプトに記載されているとおり、ファーストネームとチーム名で示します。Holly(Swift言語チーム、ジェネリクスと並行処理)、Corey(Swiftサーバーネットワーキングチーム)、Tony(Foundationと標準ライブラリ)、Doug(Swift言語チーム)。1
TL;DR
- Hollyは、もし今チームがSwiftの並行処理を設計するなら、nonisolatedなasync関数は最初から呼び出し元のコンテキストで実行されるようにする、と語りました。彼女は「非常に長い間」逆の信念を持っていましたが、実世界の証拠によって考えを変えたのです。Swift 6.2では、呼び出し元コンテキストをデフォルトとする挙動が標準になりました。1
- 繰り返された助言は、型を意図的に非
Sendableにすること。~Sendable(SE-0518、Swift 6.4で実装)はより明快な書き方を提供し、Foundationはこれまで対象外としていた型に再びアノテーションを付け直しており、UserDefaultsのグローバルインスタンスはSendable準拠を得る見込みです。21 - Coreyの非同期クリーンアップのパターン:キャンセルされたコンテキストは非同期クリーンアップを静かにスキップしてしまうため、すべての
async deferを点検し、サスペンドするawait呼び出しをキャンセルシールドで包むこと。SE-0493(asyncdefer)とSE-0504(withTaskCancellationShield)はいずれもSwift 6.4で導入されます。34 - ロードマップの率直さ:
Disconnected型はフォーラムでの現役のピッチであり、タプルの準拠は「あと一歩」だが形式上は再審議に戻されており、UniqueArrayは原則として承認され、Subprocess 1.0はリリースされ、SwiftPMはSwift Buildへ統合されつつあります。5678 - パネルに繰り返し現れたテーマ:「言語機能は収集アイテムではない」。まずプロファイルを取り、プロファイラが指し示す絞り込まれたツールだけを採用し、残りはそのまま放っておくこと。1
Appleが別の設計にするであろう並行処理の判断
Hollyの並行処理に関する振り返りは33:42あたりから始まります。このラボには公式の字幕がなく、以下のトランスクリプトはローカルのASR(自動音声認識)によるものです。
あるデベロッパーが、洗練されたセッションではめったに招かれないような問いをパネルに投げかけました。Swift 6の並行処理が現場で十分に長く使われ、その普及を観察できるようになった今、チームが今日であれば別の設計にするものはあるのか、と。Hollyはためらいなく答えました。ええ、確かにあります、と。
その具体的な悔いは、nonisolatedなasync関数がどこで実行されるか、という点にあります。2つのSwift Evolutionプロポーザルが、この挙動を正反対の方向へ動かしました。最初のものは、nonisolatedなasync関数を常にグローバルな並行スレッドプールへ移すというものでした。後のもの、Swift 6.2におけるそれは、関数を呼び出した側のコンテキストに留まらせるようにしたため、メインアクターから呼ばれた関数はメインアクターに留まります。1 Hollyはこの方針転換のきっかけを、初期の並行処理チェックフラグを実際のアプリやライブラリで使っていた人々から得た証拠にさかのぼって説明しました。彼らは非Sendableな型を、アクター隔離されたコンテキストとこれらnonisolatedなasync関数のあいだで行き来させており、グローバルプールをデフォルトとする挙動はデータ競合エラーを生んでいたのです。なぜなら、async関数が別の場所で実行されているあいだ、元のアクターがそれらの値をまだ保持していたからです。1
そして、どのセッション録画にも現れない部分がここにあります。「グローバルな並行スレッドプール上で実行することが長期的な利益にとって正しいモデルだという信念を、私は非常に長い間抱いていました」とHollyは語ります。「けれど時とともに、実世界のプロジェクトで起きた問題によって、その考えを改めることになったのです」(ASRによるパラフレーズ、約35:50)。1 Dougは当初の判断を、システム全体を見据えた擁護に値する賭けだったと位置づけました。利用可能な並行性が増えれば潜在的な並列性も増え、それがより良いパフォーマンスにつながりうる、と。そのコストは、完全な安全性モデルを人々が使い始めて初めて表面化し、あまりにも多くの型をSendableへと押しやってしまいました。それをDougは「これらすべての考えを表現する自然なやり方ではない」と表現しました。1 呼び出し元コンテキストをデフォルトとする方が親しみやすいのは、明示的に並列性を選ぶまでは非並行コードのように振る舞うからです。Swift 6.2を採用して、なぜ急に並行処理まわりが穏やかに感じられるようになったのか不思議に思ったなら、その答えは、設計した本人たちが最初のデフォルトは誤りだったと認め、その修正を出荷したことにあります。
型を意図的に非Sendableにする
このラボで最も直感に反する助言は、2年にわたる移行の習慣に逆らうものです。Hollyは、自分の型をSendableにする方法を尋ねるデベロッパーに絶えず出会うと語り、より良い問いはしばしばその逆だと言います。この型は非Sendableであるべきなのではないか?と。1 単一の計算のなかで使われる一時的な型については、明示的に非Sendableと印を付けることで、よりすっきりしたデータモデルが得られ、隔離境界を越えて渡すつもりのものとそうでないものの境界がより鮮明になります。それはパフォーマンスにも役立ちます。型を渡すコストは、そもそも移動する必要のなかった中間の値に対して払うのを避けたいものだからです。1
Swift 6.4は、この意図に実際の書き方を与えます。~Sendable(SE-0518)を使えば、利用不可の準拠を書く代わりに、ちょうど~Copyableが複製可能性を抑制するのと同じように、準拠を直接抑制できます。2 Hollyはこの違いを正確に描き出しました。利用不可のSendable準拠は、その型とすべてのサブクラスが確実にsendableでないと宣言し、それを階層全体に伝播させます。一方~Sendableは単に準拠が存在しないというだけなので、可変状態を一切追加しないサブクラスは、自身のSendable準拠を独自に追加できるのです。21
その柔軟性こそ、Foundationが必要としていたものでした。Tonyは、Foundation当初のSendable監査で出てきた3つ目のカテゴリーについて説明しました。スーパークラスは安全だが、サブクラスはそうでないかもしれないクラス、というものです。彼の例はNSStringで、これは不変でsendableですが、それに対するNSMutableStringは可変なサブクラスでsendableではありません。1 誤ったアノテーションを急いで付けるのではなく、Foundationは曖昧なクラスを非Sendableと印を付けて待ちました。今やチームはSwift 6.4のアノテーションを使ってそれらの型を正確に再アノテーションしている最中だ、とTonyはラボで述べ、標準のグローバルなUserDefaultsがSendable準拠を得ると予想しています。1 UserDefaultsの準拠と、より広範なFoundationの再アノテーションは、ラボに由来する情報として扱ってください。TonyはどちらもこのQ&Aで述べましたが、これらは公開されたプロポーザルから私が独立に確認できる機能ではありません。パネルの常々の警告はここにも当てはまります。Tonyいわく、Swift 6モードを無理に通すために@unchecked Sendableに手を伸ばしてはいけません。なぜなら、unchecked付きのアノテーションはすべて、コンパイラが証明できたはずの安全性を捨ててしまうからです。1
非同期クリーンアップを、実際に実行されるように仕上げる
Coreyはこのラボで最も実践的な訂正を担っており、それは気づかないままに出荷してしまう類いのバグです。構造化された並行処理の象徴的な勝利は、キャンセルの自動伝播にあります。あるタスクをキャンセルすれば、そのために生み出されたものもすべてキャンセルされる――ビューが閉じられたときやクライアントが切断したときに、まさにそうあってほしい挙動です。1 罠はクリーンアップに潜んでいます。途中まで書き込まれたファイルを既知の正常な状態へフラッシュする必要があるかもしれませんし、データベーストランザクションをロールバックする必要があるかもしれません。そしてそのクリーンアップ自体が非同期なのです。Coreyの言葉を借りれば、ほとんどのSwiftコードはキャンセルされたコンテキストでの実行を拒みます。できるだけ速くアンワインドすべきだと想定しているからです。そのため、キャンセルされたタスクのなかで実行される非同期クリーンアップは、その役目を静かに果たせなくなることがあります。1
その修正がキャンセルシールドであり、これは非同期deferとまさに対になります。SE-0493はdeferブロックにawait呼び出しを含められるようにし、Swift 6.4で導入されます。3 SE-0504はwithTaskCancellationShieldを追加し、これもSwift 6.4で、キャンセルが要求されていないかのようにブロックを実行することで、サスペンドするクリーンアップを完了させます。4 Coreyの監査のレシピは具体的です。それぞれのasync deferブロックを見て、そのなかのawaitが実際にサスペンドするかどうかを問うこと。もしサスペンドするものがあれば、それをキャンセルシールドで包むこと。1 彼はこの2つを「すばらしい相棒」、そして「リソースをきれいに後片付けするための実に見事な一・二のパンチ」と呼びました。1 非Sendableな型は同じ規律を補強する、とCoreyは指摘しました。並行処理のドメインを越えられない値は、非同期の制御フローを線形で推論しやすいまま保つことを強いるからです。1
Coreyによる構造化並行処理についてのより広い助言が、このセクションを締めくくります。積極的に活用しなさい、トラブルを引き起こすのは抜け道のほうだから、と。意図的に仕事を別の場所へ送り出している場合を除き、構造化されていないタスク(Task.detachedや裸のTask)は「ほとんどあらゆる犠牲を払ってでも」避け、メインの流れのなかでは決して使わないこと。タスクグループをデフォルトとし、オブジェクトのライフサイクルをその字句スコープに合わせ、線形な非同期コードを書くこと。ステップA、次にB、そしてCというレシピで、並列性に手を伸ばすのは作業が本当に分岐するときのタスクグループのなかだけにすること。1
ロードマップの率直さ
このラボはまた、パネルが出荷済みの機能と楽観的な機能とを切り分ける場でもあり、その差は、何を土台に構築するかを決めるときに重要になります。
転送された非Sendableな値を保存するという問題には、実際の答えが近づいています。今日はsendingキーワードで転送し、リージョンベースの隔離によってコンパイラが元の所有者がアクセスを手放したことを証明できますが、そうした値を保存する必要がある場合、機能するのは安全でないオプトアウトだけです。1 HollyはDisconnectedを挙げました。これは転送の性質を保存を通じて保持し、値を一旦しまっておいて後で受け渡せるようにする型のための、フォーラムでの現役のピッチです。今まさに設計され議論されているところであり、実装されてはいません。51
タプルの準拠は、形式上のステータスに対するエンジニアの楽観を示す最も鮮明な例です。タプルがEquatable、Hashable、Comparableに条件付きで準拠するまでに何が残っているのかと問われ、Hollyはそれはパラメータパックの発展形だと説明しました。要素の型がパラメータパックであるようなタプルに対する拡張を、各要素が準拠することを要求するwhere句とともに書くための構文が、言語に必要なのです。1 彼女は、実験的な実装がコンパイラのリポジトリに存在しており「あと一歩のところまで来ている」と述べました。1 形式上の記録はもっと慎重です。タプル準拠の元のプロポーザルであるSE-0283は再審議のために差し戻され、その2020年の実装は取り消されました。一般的なパラメータパックのアプローチは今日、実験的なTupleConformancesコンパイラフラグの背後にのみ存在します。10 Hollyの「あと一歩」は、出荷済みの機能ではなく、実装に対するエンジニアの正直な見立てとして読むべきです。
パフォーマンス向けのコンテナはさらに先まで進んでいます。Tonyが言及したUniqueArrayは、SE-0527(「RigidArrayとUniqueArray」、現在は原則として承認済み)に由来し、標準ライブラリに新たなContainersモジュールを導入するもので、すでにswift-collections 1.3に初期形態として収録されています。7 Tonyはこれを、コピーオンライトのretain/releaseのトラフィックがInstrumentsのトレースに現れるようなArrayのアップグレード版として位置づけました。1 Tonyが自身のお気に入りに挙げた、クロスプラットフォームのオープンソースなプロセスAPIであるSubprocessは、今年バージョン1.0をリリースします。1.0のマイルストーンは告知されているものの、最新の公開タグはまだ0.5にあるため、リリース済みではなくリリースされる段階にあります。61 ツールまわりでは、Hollyがデベロッパーが気づかないかもしれないSwiftPMの変更について説明しました。Xcodeのパッケージビルドと、オープンソースのツールチェーンのビルドが、今や1つの実装、すなわちSwift Buildを共有するようになり、それがデフォルトのビルドシステムのバックエンドになりつつあります(mainではデフォルト、6.4を目標)。81
最後に、Hollyが先頭に挙げた移行の道筋。@diagnoseは、SE-0522(「コンパイラ警告のソースレベル制御」、承認済み)による新しい属性です。9 これは警告をソースレベルで制御できるようにするもので、ある範囲では非推奨警告を抑制したり、厳格メモリ安全性や厳格並行処理のようなデフォルトでオフの警告を、最も重要な領域でオプトインしたりできます。これにより、段階的なSwift 6移行のためのより細粒度なツールとなります。1
エンジニアの助言、まとめて
このラボの価値は、セッションの尺には決して収まらない、積み重なった実践者の助言にあります。要点を、帰属とともに:
- 線形な非同期コードを書くこと。 Corey:構造化されていないタスクはほとんどあらゆる犠牲を払ってでも避け、各タスクを逐次的なレシピとして保ち、作業が本当に分岐するときにのみタスクグループのなかで並列性を導入すること。1
- MainActor移行のレシピ。 Holly:リーフ型から始めて外側へ作業を広げるか、あるいは完全にメインアクターであるべきモジュールについてはmain-actor-by-defaultをオンにして、切り離す部分を明示的にアノテーションすること。可変状態に一切触れないメソッドは
nonisolatedと印を付け、実際には一度も変更されないstatic varをletに変換してnonisolatedのままにできるようにすること。1 - 準拠のコストは一様ではない。 Doug:使われていない
EquatableやHashableの準拠は、そのウィットネスコードをバイナリに残します。実行時の存在型へのas?キャストがそれを発見できるためで、コードサイズのコストがかかります。一方Sendableは実行時表現を持たない純粋なコンパイル時のタグなので、使われていないSendable準拠は無償です。1 @inlinableと@inline(never)の組み合わせ。 Coreyのお気に入りの技:@inlinableは関数本体をモジュール境界を越えて公開し、ジェネリック特殊化と効果の伝播を解き放ちます。一方@inline(never)は、冷たくてコードの多いパス(バイト単位のフォールバックコピー)がインライン化されるのを防ぎ、熱いパスを高速に保ちます。彼はこの組み合わせを「Swiftのネットワーキングのポートフォリオ全体で3回」、異例の冷たいパスのパフォーマンス問題に対して使ってきました。1- プロジェクト全体ではなく、最も熱いパスを最適化すること。 Corey:「私たちは最も熱いパスに沿ってspanといくつかのunique arrayを導入することで、大きな成功を収めてきました」。これは、小さくコンパイラに支えられた変更で、パフォーマンス向上のほとんどすべてをもたらします。新しいパフォーマンス向けの型を隔離したまま保ち、それらの採用が決して巨大なリファクタリングを強いることのないようにすること。1
- 機能を集めるのをやめること。 パネルに繰り返し現れた一文は、Coreyが引用した友人の言葉から:「言語機能は収集アイテムではない」。すべてを使ったからといって賞がもらえるわけではありません。まずプロファイルを取り、プロファイラが指し示す絞り込まれたツール(非コピー型、
UniqueArray、Span)に手を伸ばし、残りの時間はバグ修正と機能に費やすこと。1
FAQ
AppleはWWDC26のSwiftラボを本当に字幕なしで公開したのですか?
はい。AppleはSwift Group Lab(セッション8001)を、デベロッパーサイト上で公式のトランスクリプトも字幕もない動画として掲載しました。1 正確に引用するために、私はその録画をローカルで文字起こしにかけました。そのため、この投稿のすべての引用は、おおよそのタイムスタンプ付きのそのローカルASRからのパラフレーズであり、ファーストネームとチーム名で帰属を示しています。1
Swiftチームは並行処理について何を変えると言ったのですか?
Hollyは、もしAppleが今日Swiftの並行処理を設計するなら、nonisolatedなasync関数は最初から、グローバルな並行スレッドプールへ移るのではなく、呼び出し元のコンテキストで実行されるようにする、と語りました。彼女は長い間グローバルプールの信念を抱いていましたが、実世界の証拠によって考えを変え、Swift 6.2では呼び出し元コンテキストの挙動がデフォルトになりました。1
自分のSwiftの型はSendableにすべきですか、それとも非Sendableにすべきですか?
このラボの助言は、一時的な計算用の型は意図的に非Sendableにすること、というものです。Swift 6.4はそのために~Sendableという書き方(SE-0518)を追加します。これは利用不可の準拠とは異なり、サブクラスが可変状態を一切追加しなければ依然としてSendableを追加できます。2 Tonyは、Foundationが曖昧なクラスを新機能で再アノテーションしている最中であり、グローバルなUserDefaultsがSendable準拠を得ると予想していると述べました。どちらもラボに由来する情報です。1
タスクがキャンセルされたときに非同期クリーンアップが確実に実行されるようにするにはどうすればよいですか?
キャンセルされたコンテキストでは、ほとんどのSwiftコードがサスペンドする作業をスキップするため、非同期クリーンアップが静かに失敗することがあります。Coreyのパターンは、すべてのasync deferを点検して実際にサスペンドするawait呼び出しを見つけ、それをキャンセルシールドで包むことです。async defer(SE-0493)とwithTaskCancellationShield(SE-0504)はいずれもSwift 6.4で登場します。341
タプルの準拠はSwiftで出荷されますか?
まだです。SE-0283は再審議のために差し戻され、その元の実装は取り消されました。一般的なパラメータパックのアプローチは、実験的なTupleConformancesフラグの背後にのみ存在します。Hollyはラボで、コンパイラ内の実験的な実装が「あと一歩のところまで来ている」と述べましたが、これは出荷済みの機能というよりエンジニアの楽観を反映したものです。1
このラボは、発表に対する率直な相棒です。文脈のなかで出荷済みの機能を知りたいなら、Swift 2026の新機能を読んでください。そしてHollyが論じた呼び出し元コンテキストのデフォルトの背後にある移行の仕組みについては、実践におけるSwift 6.2の並行処理をご覧ください。パネルの「まずプロファイルを取り、絞り込まれたツールを採用する」という哲学は、Swift TestingとXCTestの比較におけるテストにも及びます。WWDC26の全コーナーはApple Ecosystem Seriesにあります。
参考文献
-
Apple, WWDC 2026 session 8001, Swift Group Lab. Apple published no official transcript or captions for this lab; all quotes attributed to it are paraphrases from a local transcription of the published video, with approximate timestamps. Source for the concurrency retrospective (Holly, ~33:42), the make-types-non-Sendable guidance, the Foundation re-annotation and UserDefaults Sendable conformance (both lab-attributed to Tony), the async-cleanup and cancellation-shield pattern (Corey), the structured-concurrency and MainActor migration advice (Corey and Holly), the conformance-cost explanation (Doug), the
@inlinableplus@inline(never)combo and hottest-path performance guidance (Corey), theDisconnected, tuple-conformance,UniqueArray, Subprocess, SwiftPM, and@diagnoseremarks, and the “language features aren’t collectibles” theme. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple / Swift Evolution, SE-0518,
~Sendablefor explicitly marking non-Sendabletypes. Status: Implemented (Swift 6.4). Source for suppressing theSendableconformance and the distinction from an unavailable conformance. ↩↩↩↩ -
Apple / Swift Evolution, SE-0493, Support
asynccalls indeferbodies. Status: Implemented (Swift 6.4). Source forawaitinsidedeferblocks. ↩↩↩ -
Apple / Swift Evolution, SE-0504, Task cancellation shields. Status: Implemented (Swift 6.4). Source for
withTaskCancellationShield. ↩↩↩ -
Swift Forums, Pitch:
Disconnectedtype for modeling disconnected values. Active forums pitch for safely storing transferred non-Sendablevalues; not implemented. ↩↩ -
Apple / Swift, Subprocess — cross-platform, open-source process API announced in 2025; version 1.0 announced as releasing this year, with the latest published tag at 0.5. Status per the lab and the project’s published releases. ↩↩
-
Apple / Swift Evolution, SE-0527, RigidArray and UniqueArray. Status: Accepted in Principle; introduces a new standard-library Containers module and ships in an early form in swift-collections 1.3. ↩↩
-
Swift Forums, SwiftPM development update: default build system change. Swift Build is becoming the default SwiftPM build-system backend (default on main, targeting 6.4). ↩↩
-
Apple / Swift Evolution, SE-0522, Source-Level Control Over Compiler Warnings. Status: Accepted. Source for the
@diagnoseattribute and region-scoped warning control. ↩ -
Apple / Swift Evolution, SE-0283, Tuples Conform to
Equatable,Comparable, andHashable. Status: Returned for revision; original implementation reverted. Source for the formal status of tuple conformances against the experimentalTupleConformancesflag. ↩
