"Pretty much the same thing", that's just wrong. When you do `mySeq.add 
Child()` the compiler sees that it can implicitly upcast to the `Parent` type 
since it's a mismatched parameter. When you do `let mySeq: seq[Parent] = 
@[Child()]` there is no converter for `seq[Child]` to `seq[Parent]`. Which 
means the compiler needs to understand how to convert generic instances between 
each other and ensure it's safe.

> No, the opposite impossible to do even theoretically.

"Better to remain silent and be thought a fool than to speak and to remove all 
doubt."

It's not impossible. You have RTTI this means you can see if in the places 
where the generic specialization occurs can be converted down to the desired 
type. So in the case of the table you'd have to iterate over all instances of 
`Parent` and see that every one is `instance of Child`.

To prove this:
    
    
    import std/tables
    
    type
      Parent = ref object of RootObj
      Child = ref object of Parent
    
    converter toDerived(t: Table[string, Parent]): Table[string, Child] =
      for x in t.values: # The compiler needs to know how to do this
        if not(x of Child):
          raise (ref ObjectConversionDefect)(msg: "Could not convert table to 
derived")
      cast[Table[string, Child]](t)
    
    var
      passConv = {"bleh": Parent(Child()), "meh": Parent(Child())}.toTable
      failConv = {"bleh": Parent(Child()), "meh": Child()}.toTable
      childTable: Table[string, Child] = passConv
    childTable = failConv
    
    
    Run

Reply via email to