My experience with Swift 6 strict concurrency so far doesn't match my understanding of implicit MainActor
isolation semantics.
This is a cross-post from StackOverflow. I will link answers between both forums.
TL;DR
Build succeeds when testing a struct declared in the test module, but fails when the struct is moved to the main module:
Main actor-isolated property … cannot be accessed from outside the actor.
Steps to reproduce
- Open up Xcode 26 beta 2 on macOS 26 (probably also ok on current stables).
- Create a new Swift app with Swift testing, no storage. Call it
WhatTheSwift
. - Set the Swift Language Version on all three targets to Swift 6.
Update the default test file to be this:
import Testing
@testable import WhatTheSwift
struct WhatTheSwiftTests {
@Test func example() async throws {
let thing = Thing(foo: "bar")
#expect(thing.foo == "bar")
}
}
struct Thing {
let foo: String
}
That should build fine, and the tests should pass.
Now, move the Thing
declaration into its own Thing.swift
file in the WhatTheSwift
module, and try running the test again. You should see this:
Observations
- Marking the test
@MainActor
allows the test to pass, suggesting the compiler actually wants to isolateThing.foo
to the main actor.
My question
Why? And why only when Thing
is in a different module?