I've been hunting strange behaviour in my code base which I have reduced to the following snippet. type SNodeAny = ref object of RootObj SNode[T] = ref object of SNodeAny DNode[T] = ref object method getStr(s: SNode[float]): string {.base.} = "blahblah" method newDNode(s: SNodeAny) {.base.} = echo "newDNode base" method newDNode[T](s: SNode[T]) = echo "newDNode generic" let s = SNodeAny(SNode[float]()) newDnode(s) Run
What I expect to happen: variable `s` is a `SNode[float]` disguised as a `SNodeAny`. Calling `newDnode(s)` should dispatch the `newDnode[T](s: SNode[T])` and the string `newDNode generic` should be printed. Instead what happens is that the "super" method `newDnode(s: SNodeAny)` gets called, printing the string `newDnode base` Now the strangest part: when the `getStr()` method is removed from the code, the behaviour changes to the expected behaviour, and all is well. Alternatively, removing the `SNodeAny()` cast from the second last line also restores the expected behaviour. How does the existence of the `getStr()` method affect the behaviour of the `newDNode()` dispatch?