There's quite a lot going on here, so let me point out a few things:
Yeah the closing over the self actually matters -- only then does the "inherit actor context" happen. To be honest this is very subtle and I'm sure people just had no idea about this until executor assertions appeared.
Before that people had no real way to "notice"; since if you're not using self you're not going to observe self really... But yeah, it is somewhat confusing.
We should clarify this in the language documentation or change to something less confusing if we don't like this. I'm on the fence tbh.
cc @hborla since I think you looked into this recently.
Relatedly, please don't call internal runtime APIs: _taskIsOnExecutor. These methods may start to crash rather than return boolean values, there's no promises made about their exact behavior -- they're underscored for a reason.
There's official APIs for this: swift-evolution/proposals/0392-custom-actor-executors.md at main · apple/swift-evolution · GitHub
Using the official APIs would be just: executor.assertIsolated() or actor.assertIsolated()
But yeah, I get that you perhaps wanted to poke at the runtime to debug this particular issue. I did want to warn against doing so in general though.
By the way:
final class MySerialExecutor: SerialExecutor {
private let queue: DispatchQueue = .init(label: "Hello")
on Apple platforms you can just:
actor MyActor {
let queue: DispatchSerialQueue = ...
nonisolated var unownedExecutor: UnownedSerialExecutor {
queue.asUnownedSerialExecutor()
}
the conformance has not arrived on corelibs dispatch though...
@_inheritActorContext doesn't actually do what people think it does... Avoid touching it when you can. It doesn't actually "inherit" syntactically etc, but instead just prevents any actor hops from happening... this can yield correctness issues.
~~A proper replacement is arriving in the form of this proposal: https://github.com/apple/swift-evolution/pull/2273~~
Note: I confused that we're talking about @_unsafeInheritExecutor, more details below. The @_inheritActorContext is ok.
The executor impl is slightly wrong, as the isSameExclusiveExecutionContext will never be used, because you didn't opt your executor into complex equality:
You must do so by returning UnownedSerialExecutor(complexEquality:) from func asUnownedSerialExecutor().
We document this here: init(complexEquality:) | Apple Developer Documentation though arguably we should explicitly say on the isSameExclusiveExecutionContext that you must do this...
I'll follow up with a docs improvement PR on this.
Do note however that Dispatch's implementation is more advanced than that -- on apple platforms it can check if the queues are targeting the same queue etc.
Hope this helps,