Skip to content

Two soundness holes casting isolated conformances (SE-0470) #82550

Open
@KeithBauerANZ

Description

@KeithBauerANZ

Description

The new functionality of the cast operators to dynamically fail if not called on the main actor is currently unimplemented (#82539), but even if this is implemented, there's still two problems casting isolated conformances.

Reproduction

The first problem is where a type has an isolated conformance to a protocol which inherits from Sendable:

import Dispatch

protocol P: Sendable {
    func f()
}

@MainActor
struct S: @MainActor P {
    func f() {
        MainActor.preconditionIsolated()
    }
}

@MainActor
func example(_ s: any Sendable) {
    let p = s as! any P // on the main actor, so the cast is allowed dynamically
    DispatchQueue.global().async {
        p.f() // oops, sent it anyway
    }
}

example(S())
dispatchMain()

I believe isolated conformances should be disallowed in this case.

The second problem involves sending the result of a cast:

import Dispatch

protocol P {
    func f()
}

@MainActor
struct S: @MainActor P {
    func f() {
        MainActor.preconditionIsolated()
    }
}

@MainActor
func example(_ s: sending Any) {
    let p = s as! any P // cast is dynamically OK
    Task.detached {
        p.f() // oops, sending
    }
}

example(S())
dispatchMain()

I don't see how to resolve this without having the cast operators join the result to the calling function's region, which is definitely source-breaking in some circumstances.

Expected behavior

SE-0470 shouldn't leave soundness holes

Environment

swift-driver version: 1.127.5.3 Apple Swift version 6.2 (swiftlang-6.2.0.10.950 clang-1700.3.10.950)
Target: arm64-apple-macosx15.0

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions