Skip to content

Instantly share code, notes, and snippets.

@omochi
Created May 30, 2018 02:55
Show Gist options
  • Save omochi/e5cb7421679b122e551946864ec8d577 to your computer and use it in GitHub Desktop.
Save omochi/e5cb7421679b122e551946864ec8d577 to your computer and use it in GitHub Desktop.
https://twitter.com/slava_pestov/status/1001648778841964544
もしclassがinit制約を持つprotocolにconformしているとき、
そのclassがfinalではないなら対応するinitはrequiredでなければならない。
classのinitには2種類あることを思い出そう。designatedとconvenience。
ここでfinalでないclassのfinalなsubclassを想定する。
このfinalなsubclassがinit制約を持つprotocolにもconformしていて、
witnessは実際には親classから継承しているとする。
このとき、2つのうち1つのことが起きる。
もしwitnessがdesignated initなら、
type checkerが
ただsuper.initをよぶだけの暗黙のオーバライドを
すでに自動生成している。
いったんsubclassがfinalになれば、
protocol thunkはこのオーバライドを直接参照する。
しかしもしwitnessがconvenience initなら、
不思議な状況になる。
すべてのclassのinitは2つのエントリポイントがあることを思い出そう。
allocatingとinitializingだ。
Allocatingエントリポイントはメタタイプを受けて新しいインスタンスを返す。
Initializingエントリポイントはみ初期化なselfを受けてそれを初期化する。
前者はメモリを確保して後者を呼ぶように実装されることが想像できるだろう。
これがfinalでないclassで定義されているので、
protocol witness thunkはconvenience initializerの
virtually dispatchを求める。
しかし、requiredでないconvenience initは
allocatingのエントリポイントをvtableに持たない。
すると次に何が起こるか?
うん、コンパイラはクラッシュするだろう、
私はこれを今直している。
ここに3つの教え:
1: classのinitializerモデルはとても複雑
2: コンパイラ内部の抽象化はときどきちゃんと組み合わない
3: 言語機能の指数的組み合わせを事前にテストすることは実際できない
@omochi
Copy link
Author

omochi commented May 30, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment