😶🌫️
SE-0401 Remove Actor Isolation Inference caused by Property Wrapperの件
はじめに
Swift 5.9からのSE-0401がやばい。というかSE-0401はそもそものglobalActorがやばいのを取り消している。つまり元がやばい。
そんな感じでSE-0401の事情が少し複雑なのと現状プロジェクトによってSwiftのバージョンが違うと混乱することがあるので自分の解釈を書いておきます。
間違いがあったら指摘してもらいたいです。
本題
SE-0401はSwift 6未満である従来のglobalActorの仕様を取り消すものです。じゃあ従来からの仕様って何よっていうのを説明します。
従来からのglobalActorについて
Swift 6未満である従来のglobalActorのプローザルSE-0316 Global actor inferenceの仕様の一部では次のようなことが書いてありました。
- クラスまたは構造体が保持しているプロパティ(プロパティラッパー付き)がglobalActorを持っている時、そのglobalActorからクラス/構造体のアクターを推論してくる
- 例
- プロパティラッパーがMainActorのプロパティを保持しているとそれを使うViewがMainActorになる
- 例
具体例で説明します。
下記のCounterView
は@MainActor
と明示していないのに@UIUpdating
のintValue
を保持していると、UIUpdating
は@MainActor
のプロパティを保持してることでCounterView
が@MainActor
になる。
@propertyWrapper
struct UIUpdating<Wrapped> {
@MainActor var wrappedValue: Wrapped
}
struct CounterView { // infers @MainActor from use of @UIUpdating
@UIUpdating var intValue: Int = 0
}
SE-0401
SE-0401 Remove Actor Isolation Inference caused by Property Wrapper
このSwift 6未満の仕様であり実装されているものをSwfit 6では仕様でなくなります。
さらに、Swift 6を先取りする-enable-upcoming-feature
設定でDisableOutwardActorInference
を指定することでSwift 6未満でも上記の推論をやらなくなる。ということだと思います。
整理
- Swift 6未満
- Global actor inferenceの仕様
- クラスまたは構造体が保持しているプロパティ(プロパティラッパー付き)がglobalActorを持っている時、そのglobalActorからクラス/構造体のアクターを推論してくる
- SE-0401
- Xcode 14.3からの設定
-enable-upcoming-feature
でDisableOutwardActorInference
を指定するとSwift 6からの仕様を有効にできる
- Xcode 14.3からの設定
- Global actor inferenceの仕様
- Swift 6から
- Global actor inferenceの仕様が変わる
- 以下をやめる
- クラスまたは構造体が保持しているプロパティ(プロパティラッパー付き)がglobalActorを持っている時、そのglobalActorからクラス/構造体のアクターを推論してくる
- 以下をやめる
- Global actor inferenceの仕様が変わる
Discussion
SE-0401、とても興味深い変更ですよね…
こちらの部分ですが、SE-0401 の Proposed solution に
とありますので、「Swift 5.9 以降の Swift 5 系では
-enable-upcoming-feature DisableOutwardActorInference
でこれが有効」に、「Swift 6 からは-enable-upcoming-feature
など無くともこれが有効」になるかなと思います。ありがとうございます。なるほどそりゃそうかという感じですね。あとで修正します!