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?

Reply via email to