Skip to content

Commit b851376

Browse files
committed
Add a guide for upcoming language feature migration
1 parent 3015b62 commit b851376

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

Guide.docc/FeatureMigration.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Migrating to upcoming language features
2+
3+
Migrate your project to upcoming language features.
4+
5+
Upcoming language features can be enabled in the Swift compiler via a `-enable-upcoming-feature
6+
<FeatureName>` flag. Some of these features also support a migration mode, which will output
7+
warnings with fix-its to allow migrating to that mode. The exact semantics of such a migration is
8+
dependent on the feature, see their [corresponding
9+
documentation](https://docs.swift.org/compiler/documentation/diagnostics/upcoming-language-features)
10+
for more details.
11+
12+
## SwiftPM
13+
14+
> Note: This feature is in active development. Test with a [nightly
15+
> snapshot](https://www.swift.org/install) for best results.
16+
17+
`swift package migrate` builds and applies migration fix-its to allow for semi-automated migration.
18+
Make sure to start with a clean working tree (no current changes staged or otherwise) and a working
19+
build - applying the fix-its requires there to be no build errors and will modify files in the
20+
package *in place*.
21+
22+
To eg. migrate all targets in your package to `NonisolatedNonsendingByDefault`:
23+
```sh
24+
swift package migrate --to-feature NonisolatedNonsendingByDefault
25+
```
26+
27+
Or a target at a time with `--targets`:
28+
```sh
29+
swift package migrate --targets TargetA --to-feature NonisolatedNonsendingByDefault
30+
```
31+
32+
This will start a build, apply any migration fix-its, and then update the manifest:
33+
```
34+
> Starting the build.
35+
... regular build output with migration diagnostics ...
36+
> Applying fix-its.
37+
> Updating manifest.
38+
```
39+
40+
Check out the changes with your usual version control tooling, e.g., `git diff`:
41+
```diff
42+
diff --git a/Package.swift b/Package.swift
43+
index a1e587c..11097be 100644
44+
--- a/Package.swift
45+
+++ b/Package.swift
46+
@@ -14,10 +14,16 @@ let package = Package(
47+
targets: [
48+
.target(
49+
name: "TargetA",
50+
+ swiftSettings: [
51+
+ .enableUpcomingFeature("NonisolatedNonsendingByDefault"),
52+
+ ]
53+
),
54+
]
55+
56+
diff --git a/Sources/packtest/packtest.swift b/Sources/packtest/packtest.swift
57+
index 85253f5..8498bb5 100644
58+
--- a/Sources/TargetA/TargetA.swift
59+
+++ b/Sources/TargetA/TargetA.swift
60+
@@ -1,5 +1,5 @@
61+
struct S: Sendable {
62+
- func alwaysSwitch() async {}
63+
+ @concurrent func alwaysSwitch() async {}
64+
}
65+
```
66+
67+
In some cases, the automated application of upcoming features to a target in the package manifest
68+
can fail for more complicated packages, e.g., if settings have been factored out into a variable
69+
that's then applied to multiple targets:
70+
```
71+
error: Could not update manifest for 'TargetA' (unable to find array literal for 'swiftSettings' argument). Please enable 'NonisolatedNonsendingByDefault' features manually.
72+
```
73+
74+
If this happens, manually add a `.enableUpcomingFeature("SomeFeature")` Swift setting to complete
75+
the migration:
76+
```swift
77+
// swift-tools-version: 6.2
78+
79+
let targetSettings: [SwiftSetting] = [
80+
// ...
81+
.enableUpcomingFeature("NonisolatedNonsendingByDefault")
82+
]
83+
84+
let targetSettings:
85+
let package = Package(
86+
name: "MyPackage",
87+
products: [
88+
// ...
89+
],
90+
targets: [
91+
.target(
92+
name: "SomeTarget",
93+
swiftSettings: targetSettings
94+
),
95+
]
96+
)
97+
```

0 commit comments

Comments
 (0)