MainActor isolated protocol affects on child class but not superclass

Hey all,

I have faced following strange behavior of the swift compiler (Xcode 15.3):

class UseCase {
    func test() {
        Base().foo()
        Child().foo()
        Child().fooIsolated() // Error: Call to main actor-isolated instance method 'fooIsolated()' in a synchronous nonisolated context
    }
}

class Base {
    func foo() {
        print("Base")
    }
}
extension Base: MyProto {}

@MainActor
protocol MyProto {}

class Child: Base {
    override func foo() {
        print("Child")
    }

    func fooIsolated() {
        print("aa")
    }
}

So it seems to me that @MainActor isolated protocol applies to the Childs of the class which is conforming that protocol, but not to that base class. So as you can see from the code I have Base class and MyProto protocol which is marked as MainActor isolated. The Base class conforms MyProto protocol with extension. There is also a Child class which inherits from Base and overrides the foo function and adds its own fooIsolated function. In the UseCase class where we have non isolated context, the compiler gives an error for calling fooIsolated function of Child but not for foo functions for both Child and Base classes. From this I can say that the fooIsolated function was isolated but the interface inherited from Base and the superclass itself is not isolated.

Another strange behavior I noticed regarding the warning which we should get in this cases "Main actor-isolated class 'Child' has different actor isolation from nonisolated superclass 'Base'; this is an error in Swift 6". this warning is not fired but it should from my understanding, and it fires only when I explicitly mark Child as MainActor or the Child class was defined in different package than Base class.

Any ideas on this?

Thanks

Same issue happens on Xcode 15.4 even with brand new Xcode 16 and Swift 6.

Overridden functions must inherit the isolation of the function they are overriding, so this expected behavior. If Child.foo() were isolated, then the compiler would somehow have to prevent you from calling base.foo() in a non-isolated context only when base is actually an instance of Child. But since the compiler cannot know that at compile time, the only safe thing it can do is enforce that the isolation of the function is the same as the parent it is overriding.

That makes sense when you have an actor-isolated child whose parent is not isolated. However, that’s not the issue I’m referring to. The problem here is that the main actor-isolated protocol conformance affects the child but not the base. I believe it should not affect either of them since the conformance is added through an extension. Alternatively, if it affects the child, the parent should be affected as well.