Is your feature request related to a problem? Please describe.
Swift 6.2 lets a module opt into main-actor isolation by default (SE-0466, -default-isolation MainActor; in Xcode 26 the SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor build setting, which the new-project template enables). Under that setting, every top-level declaration without an explicit isolation is inferred @MainActor, including the public struct / public enum models the swift6 generator emits, their Codable conformances, and the extension blocks it writes for them. The generated models then cannot be used from any nonisolated context, which is where decoding normally happens (a URLSession completion, an actor-based API client, a background Task). The diagnostics take the form (Xcode 26, Swift 6.2):
conformance of 'Foo' to protocol 'Decodable' crosses into main actor-isolated code and can cause data races
main actor-isolated initializer 'init(from:)' cannot be used to satisfy nonisolated requirement from protocol 'Decodable'
Describe the solution you'd like
A swift6 generator option, for example nonisolatedModels (boolean), that when enabled emits:
public nonisolated struct Foo: Codable, … / public nonisolated enum Foo: String, … for every top-level model
nonisolated extension Foo: … for every conformance extension the generator writes (e.g. the CaseIterableDefaultsLast / UnknownCaseCheckable extensions produced under enumUnknownDefaultCase, and the oneOf enum wrappers)
- the same on the
Infrastructure/*.swift protocols and their default-implementation extensions, since a nonisolated type cannot satisfy a main-actor-isolated protocol requirement, nor take a main-actor default implementation as its witness
nonisolated extension requires Swift 6.2, so the option should probably be documented as requiring a Swift 6.2 toolchain, or emit per-member nonisolated when it is off.
Always emitting nonisolated (without the config option) would also be correct for these types, since it changes nothing for consumers on the default isolation.
Describe alternatives you've considered
additionalModelObjectAttributes: this hook inserts text on the model struct/enum line, but it does not reach the oneOf wrapper enums, inline property enums, or the conformance extension blocks, and it cannot touch the Infrastructure protocols. So a project cannot get a compiling result from it alone.
- A textual post-pass over the generated files (what we do today): a regex rewriting
^public (struct|enum) and ^extension , plus a hand-written copy of the two Infrastructure protocols with nonisolated added. It works, but it is fragile against template changes.
- Wrapping every use of a model in
MainActor.run or making the API client @MainActor: pushes decoding onto the main thread, which incurs unnecessary runtime costs.
Additional context
This is the next step after #20057: that issue made the models Sendable so they can cross an actor boundary; default MainActor isolation additionally pins them to one unless they are declared nonisolated. The generated code is plain value types with no shared mutable state, so there is no reason for it to carry actor isolation. Marking the declarations nonisolated is the correct annotation regardless of the consumer's default-isolation setting, and it is a no-op for modules that keep the Swift 6.0/6.1 default (nonisolated).
Reproduction
Generate any spec with -g swift6 --global-property models, add the output to an app target with SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor and SWIFT_VERSION = 6, and decode a model from a nonisolated function:
nonisolated func decode(_ data: Data) throws -> Pet {
try JSONDecoder().decode(Pet.self, from: data) // error: main actor-isolated initializer 'init(from:)' …
}
Generator version: 7.25.0.
Is your feature request related to a problem? Please describe.
Swift 6.2 lets a module opt into main-actor isolation by default (SE-0466,
-default-isolation MainActor; in Xcode 26 theSWIFT_DEFAULT_ACTOR_ISOLATION = MainActorbuild setting, which the new-project template enables). Under that setting, every top-level declaration without an explicit isolation is inferred@MainActor, including thepublic struct/public enummodels the swift6 generator emits, theirCodableconformances, and theextensionblocks it writes for them. The generated models then cannot be used from any nonisolated context, which is where decoding normally happens (aURLSessioncompletion, anactor-based API client, a backgroundTask). The diagnostics take the form (Xcode 26, Swift 6.2):Describe the solution you'd like
A swift6 generator option, for example
nonisolatedModels(boolean), that when enabled emits:public nonisolated struct Foo: Codable, …/public nonisolated enum Foo: String, …for every top-level modelnonisolated extension Foo: …for every conformance extension the generator writes (e.g. theCaseIterableDefaultsLast/UnknownCaseCheckableextensions produced underenumUnknownDefaultCase, and theoneOfenum wrappers)Infrastructure/*.swiftprotocols and their default-implementation extensions, since anonisolatedtype cannot satisfy a main-actor-isolated protocol requirement, nor take a main-actor default implementation as its witnessnonisolated extensionrequires Swift 6.2, so the option should probably be documented as requiring a Swift 6.2 toolchain, or emit per-membernonisolatedwhen it is off.Always emitting
nonisolated(without the config option) would also be correct for these types, since it changes nothing for consumers on the default isolation.Describe alternatives you've considered
additionalModelObjectAttributes: this hook inserts text on the modelstruct/enumline, but it does not reach theoneOfwrapper enums, inline property enums, or the conformanceextensionblocks, and it cannot touch theInfrastructureprotocols. So a project cannot get a compiling result from it alone.^public (struct|enum)and^extension, plus a hand-written copy of the twoInfrastructureprotocols withnonisolatedadded. It works, but it is fragile against template changes.MainActor.runor making the API client@MainActor: pushes decoding onto the main thread, which incurs unnecessary runtime costs.Additional context
This is the next step after #20057: that issue made the models
Sendableso they can cross an actor boundary; default MainActor isolation additionally pins them to one unless they are declarednonisolated. The generated code is plain value types with no shared mutable state, so there is no reason for it to carry actor isolation. Marking the declarationsnonisolatedis the correct annotation regardless of the consumer's default-isolation setting, and it is a no-op for modules that keep the Swift 6.0/6.1 default (nonisolated).SWIFT_DEFAULT_ACTOR_ISOLATION = MainActorfor new app targets, so this will affect a growing share of swift6 generator users.Reproduction
Generate any spec with
-g swift6 --global-property models, add the output to an app target withSWIFT_DEFAULT_ACTOR_ISOLATION = MainActorandSWIFT_VERSION = 6, and decode a model from a nonisolated function:Generator version: 7.25.0.