refactor: migrate to Swift 6 language mode#10
Merged
poolcamacho merged 1 commit intomasterfrom Apr 20, 2026
Merged
Conversation
Flips SWIFT_VERSION from 5.0 to 6.0 on every build config (Maple, MapleTests, MapleUITests × Debug / Release) and upgrades the toolchain holistically — CI runners and README requirements — so the project tracks Swift 6.3 idioms instead of shimming around older stable features. Code changes for strict concurrency: - DiffParser: enum marked nonisolated. Parsing is pure value-to-value work and is consumed by GitService (an actor) from its own isolation domain — forcing it onto MainActor (via the project-wide SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor) was the source of the errors. - DiffFile: struct marked nonisolated for the same reason; its flattened view and patch builders now run wherever the parser does. - FileWatcher: keeps MainActor isolation (it feeds @observable state the UI reads) and switches to isolated deinit so deinit can still call stop() to cancel the dispatch sources and close the FDs. This is stable on Swift 6.3; the feature shipped with Xcode 26. Tooling: - .github/workflows/ci.yml, codeql.yml, release.yml: runs-on bumped from macos-15 (Xcode 16.x, Swift 6.0 where isolated deinit is still gated behind an experimental flag) to macos-26 (Xcode 26.x, Swift 6.3 stable). - README: Swift badge 5 → 6, Requirements line updated to Xcode 26+ with a short note explaining why. Deployment target stays macOS 14.0; isolated deinit is a compile-time feature and does not raise the runtime floor. Build clean, swiftlint --strict clean.
1daf4b8 to
bcded5a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bumps
SWIFT_VERSIONfrom5.0to6.0on every build config (Maple, MapleTests, MapleUITests × Debug / Release) and fixes the three strict concurrency errors Swift 6 surfaces. No user-facing change; sets the foundation for writing new code against Swift 6 concurrency guarantees.What changed
Maple.xcodeproj/project.pbxproj—SWIFT_VERSIONflipped on all six build configs.DiffParser— markednonisolatedat the enum level. Parsing is pure value-to-value work; forcing it onto MainActor (via the project-wideSWIFT_DEFAULT_ACTOR_ISOLATION = MainActor) was the source of the errors becauseGitService(anactor) consumes it from its own isolation domain.DiffFile— same fix.flattenedand the twopatchTextbuilders now live in a nonisolated struct so they're callable from the parser.FileWatcher— stays MainActor-isolated (it talks to@Observablestate that feeds the UI), but switches toisolated deinitsodeinitcan still callstop()to cancel the dispatch sources and close the watched FDs. Swift 6 no longer lets a nonisolated deinit implicitly call a MainActor method.README.md— Swift badge bumped from 5 to 6.Decisions
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor. The rest of the project (AppState, GitCoordinator, every View) already assumes MainActor by default. Flipping that would be a much bigger refactor and is not what Swift 6 strict mode actually needs. The three outliers above are genuinely non-UI and belong off the main actor.nonisolatedat type level instead of per-member.DiffParserandDiffFileare data-only — every current member (and any future one) wants to run anywhere. Less repetition, less drift.Not in this PR
DiffParserandDiffFile.patchText. Next branch:test/parser-patch-builder.GitServicemigration toswift-subprocess(issue Migrate GitService.run from Process to swift-subprocess #7). Deferred until the library reaches 1.0.Test plan
xcodebuild -scheme Maple -configuration Debugbuilds cleanswiftlint --strictreports zero violationsCmd+S, confirm index via terminal)