I reference some AppKit code to give a real motivating use-case, but I think the issue is in the Swift compiler that ships with the Xcode 14 beta.
Compiler version: Apple Swift version 5.7 (swiftlang-5.7.0.113.202 clang-1400.0.16.2)
I have an AppKit app with modular panels that can be switched by a left side bar. Each panel has a different view controller class (derived from NSViewController
or one of its sub-classes like NSSplitViewController
). I also have two protocols MainPanelVCUp
and MainPanelVCDown
which describe the communication "upward" (from the panel up to the window) and "downward" (from the window down to the panel).
I express the type of these panels using a protocol composition, like so:
typealias MainPanelVC = MainPanelVCUp & MainPanelVCDown & NSViewController
This allows me to have an array of these panel view controllers, and treat them uniformally without coupling to their concrete types. Great!
I have a call site in one area that looks like so (abridged to focus on the relevant parts):
class RootViewController: NSSplitViewController {
var mainVC: any MainPanelVC { ... }
func replaceMainPanelVC(with newMainPanelVC: MainPanelVC) {
// ...
self.mainVC.view.removeFromSuperview()
self.mainVC.removeFromParent()
// ...
}
}
This works great. .view
and .removeFromParent()
are called on the mainVC
, which are methods that come from NSViewController
.
However, if I modify my type alias to make the existential type explicit with the any
keyword like so:
typealias MainPanelVC = any (MainPanelVCUp & MainPanelVCDown & NSViewController)
Then my call site breaks:
/.../MainSplitVC.swift:66:20: error: type of expression is ambiguous without more context
self.mainVC.view.removeFromSuperview()
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
/.../MainSplitVC.swift:67:15: error: type of expression is ambiguous without more context
self.mainVC.removeFromParent()
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
Is this a compiler bug? Or am I doing something wrong?