"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