Skip to content

Commit bf5185b

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

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

Guide.docc/FeatureMigration.md

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

0 commit comments

Comments
 (0)