Skip to content

Swift Compiler bug with MainActor isolation check #74274

Closed
@hamtiko

Description

@hamtiko

Description

I encountered unexpected behavior with the Swift compiler when dealing with MainActor isolated protocols and class inheritance. When a class conforms to a MainActor isolated protocol via an extension, the compiler will understand that the child class is isolated with MainActor which causes compilation error if the child function will be called from non-isolated context, while inherited methods from the base class do not. Additionally, a warning that should be triggered by this isolation mismatch is not consistently shown.

CC: @hborla

Reproduction

To reproduce the issue, use the following code:

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")
    }
}

In this code:

  • The Base class conforms to MyProto via extension which is marked as @MainActor isolated.
  • The Child class inherits from Base, overrides the foo method, and adds a fooIsolated method.

The compiler produces an error when calling fooIsolated from Child in a non-isolated context, but not for the foo method calls from both Child and Base.

Additionally, the expected warning "Main actor-isolated class 'Child' has different actor isolation from nonisolated superclass 'Base'; this is an error in Swift 6" is not shown unless Child is explicitly marked as @MainActor or if Child is defined in a different package than Base.

Expected behavior

  • The child class, like the base class, should not be considered as actor-isolated when the MainActor isolated protocol conformance comes from the extension.
  • The warning about different context isolation between the base and child classes should not be affected by whether they are in the same or different packages.

Environment

swift-driver version: 1.109.2 Apple Swift version 6.0 (swiftlang-6.0.0.3.300 clang-1600.0.20.10)
Target: arm64-apple-macosx15.0

I have also faced same bug with older versions (Xcode 15.3, 15.4).

Additional information

I have posted the same issue on the Swift forums to start a discussion about it: Link to discussion.

Thank you for looking into this.

Let me know if any further adjustments are needed!

Metadata

Metadata

Assignees

No one assigned

    Labels

    actorFeature → concurrency: `actor` declarationsactor isolationFeature → concurrency: Actor isolationbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.classFeature → type declarations: Class declarationscompilerThe Swift compiler itselfconcurrencyFeature: umbrella label for concurrency language featuresconformancesFeature → protocol: protocol conformancesinheritanceFeature → type declarations → class: Subclassing and inheritance of class membersswift 6.0type checkerArea → compiler: Semantic analysistype declarationsFeature → declarations: Type declarationsunexpected errorBug: Unexpected error

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions