Swift Digest
SE-0521 | Swift Evolution

Improved Syntax for Optionals of Opaque and Existential Types

Proposal
SE-0521
Authors
Tony Allevato
Review Manager
Freddy Kellison-Linn
Status
Active Review (March 16 - March 30, 2026)

01 何が問題だったのか

Swiftでは、protocol P に対して不透明型 some P と明示的な存在型 any P を書くことができます。しかし、これらにオプショナルのシュガー(?!)を組み合わせようとすると、括弧で包んで (some P)?(any P)? と書かなければなりませんでした。

Int?String? のようなオプショナル記法に慣れていると、自然に some P?any P? と書きたくなりますが、これらの記法はこれまでエラーになっていました。パーサが some (P?)any (P?) として解釈してしまい、some / any の後ろにはprotocolが来る必要があるのに P?(= Optional<P>)はprotocolではない、という理由で弾かれていたためです。

// 今までは括弧が必須
let x: (any P)?
let y: (some P)?

// これはエラー(some (P?) / any (P?) と解釈される)
let x: any P?
let y: some P?

将来的にSwiftがexistential typesで any の明示を必須にする方向に進むと、オプショナルの存在型を書くたびに括弧が増えてしまい、可読性や書き味を損ねる懸念がありました。some P? / any P? が「P に適合する不透明型/存在型のオプショナル」以外の意味を持つことは考えにくく、この直感的な書き方を素直に受け入れるパーサに変える必要がありました。

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

some P?(some P)? と、any P?(any P)? と同じ意味になるようパーサの優先順位を変更します。some / any の直後に続くprotocol型の末尾に付いた ? / ! を、some / any 全体を囲むように持ち上げて解釈するイメージです。

// 以下はすべて等価に書けるようになります
let a: any P? = nil       // (any P)?
let b: some P? = nil      // (some P)?
let c: any P! = nil       // (any P)!

オプショナルの多重化にも対応し、some P??(some P)?? と解釈されます。また、暗黙アンラップドオプショナル(!)が許される位置では同じ規則で any P! も使えます。

protocol composition

protocol composition(P & Q)と組み合わせる場合は、これまでどおり composition を括弧で囲む必要があります。括弧で囲まれていれば新しい記法と併用でき、(any P & Q)? に加えて any (P & Q)? も書けるようになります。

// いずれも (any P & Q)? と同じ意味
let x: (any P & Q)? = nil
let y: any (P & Q)? = nil

一方で、括弧なしで any P & Q? と書くのは引き続きエラーです。新しいパースルール上は「P & Q に適合する存在型のオプショナル」と解釈することも技術的には可能ですが、postfixの ? が長めのprotocol compositionと any キーワードまでまとめて覆うのは読み手にとって紛らわしいため、あえて許容しない判断がされています。この場合はコンパイラが専用の診断を出し、any (P & Q)? のように括弧を補うfix-itを提示します。

既存の any fix-it の更新

-enable-experimental-feature ExistentialAny 下で、protocol型をそのまま型として使っている箇所には「any P と書くべき」という警告とfix-itが出ます。これまでfix-itは (any P) と括弧付きで挿入されていましたが、単一のprotocol制約でオプショナル(もしくは暗黙アンラップドオプショナル)の場合は、新しい記法に合わせて括弧のない any P を挿入するようになります。

let x: P?
// 旧: fix-it は (any P)? を提案
// 新: fix-it は any P? を提案

既存コードはすべてそのまま有効で、(some P)?(any P)? のように明示的に括弧を書いているスタイルもこれまでどおり使えます。型のマングリングも変わらないため、ABIや API resilience への影響もありません。