Effects of explicit nonisolated on isolation inference

I’m having difficulty explaining some behavior I’ve noticed. The following code compiles. But if you mark either protocol as nonisolated, it appears to cut off the MainActor isolation inference for MyClass.requirement.

I find this a little surprising when applied to A, and very surprising when applied to B.

// default: nonisolated

protocol A {
	func requirement()
}

protocol B: A {
}


@MainActor
final class MyClass: @MainActor B {
	var state = 1

	init() {
	}

	func requirement() {
		// if either protocol is explicitly nonisolated:
		// Error: Main actor-isolated property 'state' can not be referenced from a nonisolated context
		print(state)
	}
}

This came up in the context of using default MainActor, which can motivate adding explicit nonisolated where you otherwise wouldn’t need it.

I’ve re-read SE-0449, but I wasn’t able to find a clear justification for this behavior. Did I miss something?

2 Likes

not an answer, but to further add to the confusion... indirecting through another protocol refinement produces different behavior (which also makes me think there is a bug involved somewhere):

protocol A {
	func requirement()
}
protocol B: A {}
nonisolated protocol C: B {}

@MainActor
final class MyClass: @MainActor C
{
	var state = 1
	init() {}

	func requirement() {
		print(state) // ✅ – still inferred to be @MainActor
	}
}

also, if you declare the conformance via an extension, it appears to behave differently:

protocol A {
	func requirement()
}
nonisolated protocol B: A {}

@MainActor
final class MyClass
{
	var state = 1
	init() {}

	func requirement() {
		print(state) // ✅
	}
}

extension MyClass: @MainActor B {}

i find myself currently struggling to formulate how i think these feature interactions even should work... do you feel you have a sense for that? my intuition is that the explicit isolated conformance being written on the class declaration should 'get priority' over the protocols being marked nonisolated.

cc @hborla @Douglas_Gregor – curious if either of you could shed light on what's happening in these cases, or what the intended interaction between isolated conformances and 'global actor inference cutoff' should be.

5 Likes