🥕

SE-0441 Pitch: Formalize ‘language mode’ terminology メモ

に公開

SE-0441について

URL

SE-0441 Pitch: Formalize ‘language mode’ terminology

背景

  • swiftコンパイラ自体のバージョンとコンパイルする言語モードのバージョンが存在する
    • 具体例
      • Swift 6のコンパイラでSwift 5の言語モードでコンパイルする
  • コンパイラ自体のバージョンではなく言語モードを-swift-versionと呼んでた
    • バージョンにはコンパイラと言語モードの2つあり、言語モードを-swift-versionと名付けられているのが紛らわしい

行われること

  • 言語モードの名称を-swift-version から-language-modeと変更する
    • -swift-versionは非推奨
  • SPMでも
    • swiftLanguageVersionsswiftLanguageModesにリネーム
  • CLIでも
    • swift build -swift-version 5swift build -language-mode 5にする

理解の補足

コンパイラバージョンと言語モード

コンパイラバージョン 言語モードオプション 説明
Swift 5.3 -swift-version 4.2 Swift 4.2モードでコンパイル
-swift-version 5 Swift 5.0モードでコンパイル
-swift-version 5.1 Swift 5.1モードでコンパイル
-swift-version 5.2 Swift 5.2モードでコンパイル
-swift-version 5.3 Swift 5.3モードでコンパイル
Swift 6.0 -swift-version 4.2 Swift 4.2モードでコンパイル(非推奨)
-swift-version 5 Swift 5.0モードでコンパイル(非推奨)
-swift-version 5.1 Swift 5.1モードでコンパイル(非推奨)
-swift-version 5.2 Swift 5.2モードでコンパイル(非推奨)
-swift-version 5.3 Swift 5.3モードでコンパイル(非推奨)
-language-mode 4.2 Swift 4.2モードでコンパイル
-language-mode 5 Swift 5.0モードでコンパイル
-language-mode 5.1 Swift 5.1モードでコンパイル
-language-mode 5.2 Swift 5.2モードでコンパイル
-language-mode 5.3 Swift 5.3モードでコンパイル
-language-mode 6 Swift 6.0モードでコンパイル

-swift-versionという表記は非推奨。

具体例

  • アプリのコンパイラバージョンをSwift 6.0
    • language-modeをSwift 5.3にする
    • language-modeをSwift 6.0にする

別の例え

  • たとえば
    • PS 2実機でPS 1のソフトを動かすとき、-ps-version 1と呼んでたという感じ?

互換性

  • Xcode 16のSwift 6コンパイラを使うとき複数のlanguage-modeを使える
    • 対応するlanguage-modeは下の通り
      • Swift 6、Swift 5、Swift 4.2, Swift 4.0
    • これはモジュール別に指定できる
      • Swift 6コンパイラを扱う1プロジェクトで複数のlanguage-modeを指定できる
        • たとえば
          • アプリ自体は-language-mode 5.3だが、DB用のモジュールは-language-mode 6
          • 現状はこの-language-mode-swift-versionと呼ばれてる

https://docs.swift.org/swift-book/GuidedTour/Compatibility.html

実際の記述

実際に「コンパイラバージョンを6」とし、「language-modeを5」にすることを考えます。

気にするのは下記3つです。

  • swift-tools-versionを6.0
    • コンパイラバージョン
  • enableExperimentalFeature
    • language-modeを5に下げる理由は大抵Strict Concurrencyをtargetedにしたいんでしょ
  • swiftLanguageModesをv5
    • language-mode
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

let package = Package(
    name: "FlakyTestQuiz",
    platforms: [
        .iOS(.v17),
    ],
    products: [
        .library(
            name: "FlakyTestQuiz",
            targets: ["FlakyTestQuiz"]),
    ],
    dependencies: [
    ],
    targets: [
        .target(
            name: "FlakyTestQuiz",
            swiftSettings: [ // 個別のターゲットごとに
                .swiftLanguageMode(.v5)
            ]
        ),
        .testTarget(
            name: "FlakyTestQuizTests",
            dependencies: [
                "FlakyTestQuiz"
            ],
            swiftSettings: [
                .enableExperimentalFeature(
                    "StrictConcurrency=targeted"
                )
            ]
        ),
    ]
)

https://www.avanderlee.com/concurrency/swift-6-migrating-xcode-projects-packages/

考察

swift-tools-versionとは何か

  • swift-tools-versionはあくまでパッケージのための最低限必要なコンパイラのバージョン
      • swift-tools-version: 5.4と指定しても、ビルドするmacOSにXcode 16がインストールされておりtool-chainとしてswift 6が利用されていればswift 6でビルドされる

swiftLanguageModesとは何か

  • swiftLanguageModesはフラグなどで有効/無効になるモードの指定を一気に変えられる
      • swiftLanguageModes: 6にするとSwift 5でupcoming feature flagだったものを全てYESにする
  • swiftLanguageModesはswift-tools-versionよりも小さく指定しなければいけない
      • swiftLanguageModes: 6を指定し、swift-tools-version: 5は矛盾しているのでその指定はできない

Discussion