😬

[Swift6に向けて] SE-0352: Implicit Opened Existentials

2024/05/30に公開

要約

SE-0352: Implicit Open Existentials

存在型を関数のGenericなパラメータに渡すときに、具体的な型に展開されて扱われるようになる。
結果、これまでコンパイルできなかったコードがコンパイルできるようになる。
暗黙的(Implicit)に、存在型(Existentials)が展開(Open)される。

Proposalの内容

モチベーション

存在型(Existential Type)は、動的に変わる型を表現するのに便利な型である。
その動的な性質のため、使用方法において多くの制限がある。
特に、Genericsと組み合わせて使うときによくエラーになる。
よく見るエラー →(e.g. "protocol 'P' as a type cannot conform to itself")

protocol P {
  associatedtype A
  func getA() -> A
}

func takeP<T: P>(_ value: T) { }

func test(p: any P) {
  takeP(p) // error: protocol 'P' as a type cannot conform to itself
}

Genericsを使用している箇所を存在型に置き換えるのは簡単だが、その逆は、一般的に難しい。
上記のコードが許可されてないことによって、修正が要求され、メンテナンスが難しいコードになってしまうのは、"罠"ともいえる。
存在型とGenericsをもっと楽に組み合わせて使えるようにしたい。

新しい提案

Genericsパラメータに存在型が渡されるときに、存在型を暗黙的(Implicit)に展開(Open)して、実際の型(Underlying Type)として渡す。
Genericに存在型の実際の型を当てはめることで、上記のエラーが発生しなくなる。

これまではコンパイルできなかったコードがコンパイルできるようになる。
Genericsと存在型のやりとりがスムーズになるため、コードをよりシンプルに記述できるようになる。
暗黙的に展開されるだけで、開発者側は意識せずに恩恵を受けることができる。

既存のコードとの互換性

  • これまでコンパイルが通らなかったコードがコンパイルできるようになる。
  • 選択されるオーバーロードが変わる可能性がある。(恐らくレアケース)

影響がありそうなこと

  • 選択されるオーバーロードが変わる可能性がある。

Refs

Discussion