build: adopt the Swift 6 language mode across the app, plugins and packages - #2311
Merged
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
1 similar comment
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
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.
Moves the whole project to the Swift 6 language mode, which is the newest the toolchain accepts (
-swift-version 6.1,6.2and7are all rejected; Swift 6.4 is the compiler, 6 is the language mode).Configs/Base.xcconfigSWIFT_VERSION = 5.06.0Packages/TableProCore,Packages/TableProOracleswift-tools-version: 5.96.0.swiftformat--swiftversion 5.96.0LocalPackages/(the vendored CodeEdit forks) stays on 5.9 so it can still take upstream changes. An xcconfig does not reach SwiftPM targets, which is why the two first-party packages need their own manifest bump; that trap is now written down inCLAUDE.mdalong with the reason never to test a language-mode change by passingSWIFT_VERSION=on thexcodebuildcommand line.What the compiler actually made us fix
ISO8601DateFormatter,ByteCountFormatterandRelativeDateTimeFormatterare notSendable, so shared statics now sit behindOSAllocatedUnfairLock.DateFormatter,NumberFormatterandDateComponentsFormatteralready carryNS_SWIFT_SENDABLEin the macOS 26 SDK and were left alone.NSLock.lock()/unlock()insideasyncbodies is a hard error in Swift 6. Converted to scopedwithLockacross 12 plugins and app areas. Every critical section keeps the exact statements it had, including the multi-exit shapes whereunlock()sat before an earlyreturn.deinit.NSEvent/NotificationCentertokens typedAny?orNSObjectProtocol?cannot be touched from a nonisolateddeinit, so they moved behind a lock.PluginPrivilegeScope,PluginImportFieldType,PluginBooleanSynonym,PathFieldRole,AutoLimitStyleandSQLDialectDescriptor.BooleanLiteralStylegained@unknown default, which is whatCLAUDE.mdalready asks for on an open domain.Sendableconformances added to protocols and value types that were already thread-safe:SupervisedProcessRunner,KeyValueStore,ForeignAppImporter,KeyCode, theExportable*andConnectionImport*transfer types, and several storage singletons.nonisolatedon loggers inside@MainActortypes, on pure statics, and across the iOS driver, platform, security and intent layers, which run underSWIFT_DEFAULT_ACTOR_ISOLATION = MainActorand are background code by nature.MCPAuditLogStorage,SQLFavoriteStorage,QueryHistoryStorage, plusLinkedSQLIndex) moved from aninit-time bootstrap, which Swift 6 rejects, to a handle that prepares itself on first use.static let sharedwas already lazy, so first touch is still first use.A regression this caught in the migration itself
The first attempt replaced
CSVTypeInferrer'sISO8601DateFormatterwithDate.ISO8601FormatStyle. A 329-input probe showed" 2026-08-20","2026/08/20"and"-0001-01-01"would have stopped being inferred as dates, so a CSV column of slash-separated dates would have imported as text. Reverted to the original formatters behind a lock. The newCSVTypeInferrerTestspins those three cases plus the lenient forms the formatter accepts, and runs in CI through theTableProCorepackage job.A second, subtler one: a pure
static funcon a SwiftUIViewbecomes main-actor isolated in Swift 6, and calling it from a nonisolated test traps at runtime rather than failing to compile. That crash took down 2,410 tests in one run. Fixed by marking those helpersnonisolated; a scan found and fixed all three occurrences.Verification
CSVTypeInferrerTests.swiftlint lint --strictclean over the app,Plugins/,Packages/,TableProMobile/and the test targets.The 27 macOS failures: six suites are the known local environment failures (network, pasteboard, timers), four are timing-flaky and pass in isolation, and the rest fail on code this branch never touches.
PreferenceKeysGuardTeststrips onremoveValue(forKey: "extensions")inCLI/BridgeProxy.swift;URLClassifierTestson the new DuckDB file classification;ThirdPartyLicenseInventoryTestsonDUCKDB_VERSIONmissing from a build script;TabExecutionSettleGuardTestsonMCPProtocolDispatcher+Requests.swift;StringCatalogIntegrityTestsandKoreanLocalizationSourceTestson.xcstringscontent. The two.xcstringsfiles were already uncommitted before this work started and are deliberately left out of this branch.Reviewer notes
SettablePluginDiscoverable.settingsView()gained@MainActorandExportFormatPlugin/ImportFormatPlugingainedSendable. Isolation and marker-protocol conformances do not change mangled symbols or witness-table layout, so already-shipped plugins keep loading and nocurrentPluginKitVersionbump is needed. It is a source-level change for a third-party plugin author, whosesettingsView()now has to be@MainActor. Please runscripts/check-pluginkit-abi.sh <merge-base>before merging; nothing in CI does it and I did not run it.CopilotChatProviderand the eight export/import plugins carry@unchecked Sendableover genuinely unsynchronised mutable state. Swift 5 was not checking them; making them safe is a redesign of how plugin settings are read during an export, not part of a language-mode bump.XLSXWriter.write(to:)is nowasyncand does the zip build and file write inside its detached task, taking only[ZipFileEntry]across the boundary. Same work, same thread, nothing non-Sendable crossing.