I did more experiments on this issue. Below is my summary.
TLDR: the behavior is inconsistent between Swift 6.3.3 and nightly; changing code slightly causes inconsistent behaviors in nightly too.
(Note: I didn't use 6.4 because it's not available on compiler explorer).
The setup:
protocol AsyncRequirement {
@concurrent func work() async
}
@MainActor
class ConformingType: @MainActor AsyncRequirement {
func work() async {
}
}
func test1() -> some AsyncRequirement {
ConformingType()
}
func test2() {
let value: some AsyncRequirement = ConformingType()
_ = value
}
@MainActor
func test3() {
let value: some AsyncRequirement = ConformingType()
_ = value
}
nonisolated(nonsending)
func test4() async {
let value: some AsyncRequirement = ConformingType()
_ = value
}
nonisolated(nonsending)
func test5() async {
let value: some AsyncRequirement = ConformingType()
await value.work()
}
Test results:
-
test3compiles in all Swift versions. This is as expected. -
Swift 6.3.3: All tests except
test3fail to compile and ouput the same error.error: main actor-isolated conformance of 'ConformingType' to 'AsyncRequirement' cannot be used in caller isolation ... context [#IsolatedConformances]I think the behavior is simple, consistent, and easy to understand.
-
Nightly: tests have different behaviors
test1andtest2: fail with the same error as in Swift 6.3.3.test4: it compiles. No warning or error.test5: it compiles with a warning (the one @mattie mentioned in the original post)
I probably understand the different behaviors of
test4andtest5. It appears that isolated conformance implementation in recent releases is different from what's proposed in the original proposal. Compiler produces diagnostic only when the code would actually call methods of isolated confomrance in a different isolation (see my earlier question about this). But iftest4compiles, I thinktest1andtest2should compile too?
Another test. It does the same as test5 but uses generic function. It fails to compile in nightly. Note the "cannot satisfy conformance requirement for a 'Sendable' type parameter" part in the error message. I don't quite understand what it meant.
nonisolated(nonsending) func useThem<T: AsyncRequirement & Sendable>(value: T) async {
await value.work()
}
nonisolated(nonsending) func test6() async {
useThem(value: ConformingType()) // error: main actor-isolated conformance of 'ConformingType' to 'AsyncRequirement' cannot satisfy conformance requirement for a 'Sendable' type parameter [#IsolatedConformances]
}
I'd appreciate if anyone in Swift team can clarify if the behaviors in nightly is by design or a regression.