danielinoa
(Daniel Inoa)
1
Hello,
Does anyone know the rationale behind Swift favoring static dispatch in this context (attached screenshot), instead of considering witnesses within the class hierarchy?
Thanks in advance for your answer.
Nevin
2
6 Likes
danielinoa
(Daniel Inoa)
3
Good to see it is on the community's radar.
I'm puzzled as to why this bug has not yet been addressed since 2015.
Itâs not really a bug but rather a consequence of how protocol conformances work, but we should probably emit a warning in this situation.
4 Likes
Jumhyn
(Frederick Kellison-Linn)
6
If a superclass A conforms to P but uses a default implementation for one of the requirements (echo), then there is no âslotâ in the class vtable for a A corresponding to the echo requirement. As a subclass, B doesnât get its own unique conformance to Pârather it has to reuse Aâs conformance, including the âuse default echo implementationâ part of that conformance. And since A has no actual echo method, B cannot override the default implementation that A used. So even if there is an echo method on B, itâs not registered as being part of the conformance.
3 Likes
xwu
(Xiaodi Wu)
7
It is not (notionally) statically dispatched. There is only one witness to the protocol requirement and it is the extension method, for the reasons outlined above by @Jumhyn.
The emitted warning should say that the concrete method echo shadows but does not override the default implementation.
4 Likes
I think you mean there's no slot in the class vtable, not in the protocol conformance. A protocol conformance always records an implementation for each protocol requirement. If the implementation is declared in a protocol extension, the corresponding entry points at the protocol extension method. If the implementation is declared inside a class, the entry points at a thunk which loads the entry from the class's vtable and calls it. Method overrides in a subclass are implemented by the subclass replacing the vtable entry with its own implementation.
4 Likes
This behavior falls out from the table-driven dispatch used for protocol conformances and class methods. To allow a subclass to override a default implementation would require a more general dispatch mechanism, like objc_msgSend() or similar.
1 Like
Jumhyn
(Frederick Kellison-Linn)
10
Ah, yeah, you're rightâI misremembered the details here. Edited to clarify, thank you!
Nevin
11
Technically, it would only require that when the conformance is declared via an extension to the class.
If the conformance is declared at the class definition site, then it would theoretically be possible for the compiler to include these methods within the class vtable âas ifâ they had been written out manually.
1 Like
Yes, you're absolutely right, but the extension thing means it's still a leaky abstraction and the limitations of table dispatch cannot be completely papered over.
1 Like
Nevin
13
I wonder if there might someday be a way to let people make it explicit. Like â@allowDefaultOverrides(Protocol)â within the main body of a class or something.
1 Like
Jumhyn
(Frederick Kellison-Linn)
14
If we introduced a way to refer to the default implementation directly rather than only via witness (e.g. via some fully-qualified name syntax), classes could make this explicit by providing the echo() function and having the implementation be, say:
self.P::echo()
5 Likes