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?