Was ist der “Swift-6-Modus”?
Swift 6 wird nicht mehr 2023 veroeffentlicht, das wurde von Doug Gregor aus der Swift Language Workgroup klargestellt. Aber wusstest du, dass Apple bereits Teile von Swift 6 in Version 5.8 ausgeliefert hat? Ja, das stimmt. Einige Teile von Swift, die mit Xcode 14.3 vor ein paar Wochen ausgeliefert wurden, sind standardmaessig deaktiviert. Sie werden eingeschaltet, sobald Swift 6 erscheint, was noch ein Jahr dauern koennte – oder sogar laenger.
Diese Features fuehren einige Breaking Changes in Swift ein, zum Beispiel durch Umbenennung bekannter APIs, Anpassung ihres Verhaltens oder neue Sicherheitspruefungen im Compiler. Aber sie werden alle irgendwann aktiviert, um unsere Codebasen zu verbessern. Und wir werden unsere Projekte entsprechend anpassen muessen.
Ich dachte mir, es waere eine gute Idee, alle Features in meinen Projekten zu aktivieren, um zu sehen, ob es Breaking Changes fuer meine Codebasis gibt, die ich kennen sollte. Und natuerlich koennte ich auch einige neue Features nutzen, wie BareSlashRegexLiterals, das die /.../-Regex-Literal-Syntax fuer kompakte Regex-Initialisierung verfuegbar macht.
Gluecklicherweise gibt es mit Swift 5.8 jetzt einen einheitlichen Weg, diese Optionen zu aktivieren: Wir muessen einfach -enable-upcoming-feature an Swift uebergeben, indem wir es in den OTHER_SWIFT_FLAGS in den Build Settings unseres Projekts in Xcode angeben. Aber wir muessen auch wissen, welche Features verfuegbar sind, und ich konnte keinen Ort mit einer guten Uebersicht finden (noch nicht). Der Vorschlag, der diese einheitliche Option eingefuehrt hat, enthaelt eine solche Liste, aber sie wird nicht mit neueren Optionen aktualisiert, die spaeter hinzugefuegt werden, wie die von SE-0384. Wo koennen wir also derzeit zuverlaessig eine Liste aller unterstuetzten Optionen bekommen?
UPDATE: Du kannst jetzt direkt auf Swift.org nach Upcoming Flags filtern.
Swift ist Open Source, also scheint der zuverlaessigste Ort das Swift-GitHub-Repository zu sein! Es enthaelt eine Features.def-Datei, die Eintraege (Link zum release/5.8-Branch) namens UPCOMING_FEATURE beinhaltet, einschliesslich der zugehoerigen Swift-Evolution-Vorschlagsnummer und der Swift-Version, in der sie aktiviert werden:
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)
UPCOMING_FEATURE(BareSlashRegexLiterals, 354, 6)
UPCOMING_FEATURE(ExistentialAny, 335, 6)Hier sind die Optionen mit einer kurzen Beschreibung, was sie tun:
ConciseMagicFile: Aendert#file, sodass es#fileIDstatt#filePathbedeutet.ForwardTrailingClosures: Entfernt die Backward-Scan-Matching-Regel.ExistentialAny: Verlangtanyfuer existenzielle Typen.BareSlashRegexLiterals: Macht die/.../-Regex-Literal-Syntax verfuegbar.
Aus irgendeinem Grund scheinen zwei Optionen dort nicht aufgefuehrt zu sein (ich untersuche es):
StrictConcurrency: Fuehrt vollstaendige Concurrency-Pruefung durch.ImplicitOpenExistentials: Fuehrt implizites Oeffnen in zusaetzlichen Faellen durch.
Weitere Optionen werden mit spaeteren Versionen ausgeliefert, z. B. ImportObjcForwardDeclarations.
Um meinen Code zusaetzlich auf korrekte Concurrency-Unterstuetzung zu pruefen, habe ich mich entschieden, auch -warn-concurrency (das sollte eigentlich dasselbe wie StrictConcurrency sein, falls das tatsaechlich funktioniert) und -enable-actor-data-race-checks zu uebergeben.
Mein Projekt migrieren
Wenn du wie ich alle 5.8-Optionen in deinem Projekt aktivieren moechtest, kopiere (Cmd+C) den folgenden Textblock, gehe dann zum Tab “Build Settings” deines Xcode-Projekts, suche nach “Other Swift Flags”, waehle diese Option im Editor aus und fuege sie ein (Cmd+V):
//:configuration = Debug
OTHER_SWIFT_FLAGS = -enable-upcoming-feature BareSlashRegexLiterals -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature StrictConcurrency -warn-concurrency -enable-actor-data-race-checks
//:configuration = Release
OTHER_SWIFT_FLAGS = -enable-upcoming-feature BareSlashRegexLiterals -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature StrictConcurrency -warn-concurrency -enable-actor-data-race-checks
//:completeSettings = some
OTHER_SWIFT_FLAGS
Wenn du wie ich eine mit SwiftPM modularisierte App verwendest oder an einem Swift-Package arbeitest, musst du zusaetzlich ein Array von .enableUpcomingFeatures an jedes Target ueber swiftSettings uebergeben:
let swiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("BareSlashRegexLiterals"),
.enableUpcomingFeature("ConciseMagicFile"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("ForwardTrailingClosures"),
.enableUpcomingFeature("ImplicitOpenExistentials"),
.enableUpcomingFeature("StrictConcurrency"),
.unsafeFlags(["-warn-concurrency", "-enable-actor-data-race-checks"]),
]
let package = Package(
// ...
targets: [
// ...
.target(
name: "MyTarget",
dependencies: [/* ... */],
swiftSettings: swiftSettings
),
// ...
]Vergiss nicht, deine Tools-Version am Anfang der Datei auf 5.8 zu aktualisieren:
// swift-tools-version:5.8.enableUpcomingFeature ist erst ab Swift 5.8 verfuegbar
Das liegt daran, dass Swift die Optionen, die du fuer dein Projekt-Target angegeben hast, nicht automatisch an importierte Module weitergibt. Und das sind gute Neuigkeiten, denn so muessen Swift-Packages, die du moeglicherweise in dein Projekt einbindest, nicht angepasst werden, und du kannst diese Features trotzdem fuer deinen eigenen App-Code nutzen. Und umgekehrt: Package-Autoren koennen diese Features fuer ihre Projekte aktivieren, ohne den Code in Projekten zu beeinflussen, in die sie eingebunden werden.
Nachdem ich alles aktiviert und gebaut hatte, stiess ich auf vier Arten von Problemen:
Ich musste an mehreren Stellen das
any-Keyword hinzufuegen – Xcode half mit einem Fix-It:


Aus irgendeinem Grund erhielt ich viele Fehler bei Views mit einem
.sheet-Modifier. Die Fehlerpaare besagten: “Generic parameter ‘Content’ could not be inferred” und “Missing argument for parameter ‘content’ in call”. Diese Meldungen waren aber nicht sehr hilfreich, also versuchte ich zuerst, den.sheet-Inhalt durch eine einfacheText-View zu ersetzen – aber das half nicht. Also habe ich die Optionen einzeln deaktiviert und die Fehler verschwanden, als ichForwardTrailingClosuresausschaltete – also liess ich es deaktiviert. Ich hoffe, dass zukuenftige Swift-Versionen eine bessere Fehlermeldung erzeugen, um die Fehler spaeter zu beheben. Es eilt nicht. Ich kann es mit Swift 5.9 erneut versuchen. Ich hatte jetzt keine Zeit zum Untersuchen.

Ich musste einige meiner Funktionen, die einen TCA-
WithViewStorezurueckgeben, mit dem@MainActor-Attribut markieren – aber auch hier half Xcode mit Fix-Its.

An vielen Stellen wurden Warnungen angezeigt: “Non-sendable type ‘…’ passed in call to main actor-isolated function cannot cross actor boundary”. Also habe ich diese Typen dem
Sendable-Protokoll konform gemacht (mehr ueberSendablehier).
Alles andere schien fuer meine App RemafoX mit ~35.000 Zeilen Swift-Code problemlos zu bauen. Der gesamte Prozess hat mich weniger als 3 Stunden gekostet.
Mein Projekt ist jetzt bereit fuer die Zukunft von Swift und ich kann das neue Regex-Literal-Feature nutzen (let regex = /.*@.*/). Ausserdem kann ich keinen neuen Code einfuehren, den ich spaeter zu Swift 6 migrieren muesste, da ich sofort Fehler erhalte.
Wie sieht es bei deinem Projekt aus? Welche Upcoming Features moechtest du migrieren?

