Opt into dynamic dispatch?

As the common default-implementation-override gotcha captured in [SR-103] Protocol Extension: function's implementation cannot be overridden by a subclass · Issue #42725 · apple/swift · GitHub is still open, is there any way to force dynamic dispatch on protocol extension methods?

Joe mentions in Proposal: Universal dynamic dispatch for method calls - #2 by Joe_Groff two missing pieces of Swift:

  • the ability for extensions to protocols to add new dynamically-dispatched methods, and
  • compiler quality work to diagnose confusing cases where concrete types obviously shadow non-dynamic protocol extensions.

We could force dynamic dispatch of method calls instead at the build level with some compiler flag to let users opt in, for example.

or introduce the dynamic keyword on protocols:

public extension ViewPresenting {
    dynamic func present(_ viewController: UIViewController) {
        // ... always dispatch this dynamically so overrides are reliably called
    }

It's the class side that needs to introduce the dispatch; the protocol doesn't care. The annotation would have to be on the conforming class. The way to "force dynamic dispatch" today is provide an explicit implementation of the requirement as a method on the class, so that it receives a vtable slot and can be overridden by subclasses.

1 Like