😶‍🌫️

SE-0401 Remove Actor Isolation Inference caused by Property Wrapperの件

2023/08/30に公開
2

はじめに

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と明示していないのに@UIUpdatingintValueを保持していると、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-featureDisableOutwardActorInferenceを指定するとSwift 6からの仕様を有効にできる
  • Swift 6から
    • Global actor inferenceの仕様が変わる
      • 以下をやめる
        • クラスまたは構造体が保持しているプロパティ(プロパティラッパー付き)がglobalActorを持っている時、そのglobalActorからクラス/構造体のアクターを推論してくる

Discussion

treastrain / Tanaka Ryogatreastrain / Tanaka Ryoga

SE-0401、とても興味深い変更ですよね…

  • Swift 5.9から
    • SE-0401
  • Swift 5.8でも
    • Xcode 14.3からの-enable-upcoming-featureを設定でSE-0401が使える?
      • DisableOutwardActorInference

こちらの部分ですが、SE-0401 の Proposed solution

The proposal is simple: In the Swift 6 language mode, property wrappers used within a type will not affect the type's actor isolation. We simply disable this inference step entirely.

In the Swift 5 language mode, isolation will continue to be inferred as it currently is. The new behavior can be requested using the -enable-upcoming-feature DisableOutwardActorInference compiler flag.

とありますので、「Swift 5.9 以降の Swift 5 系では -enable-upcoming-feature DisableOutwardActorInference でこれが有効」に、「Swift 6 からは -enable-upcoming-feature など無くともこれが有効」になるかなと思います。

yimajoyimajo

ありがとうございます。なるほどそりゃそうかという感じですね。あとで修正します!