type
A = ref object of RootObj
i : int
B = ref object of A
j: int
proc test1(x: A) =
echo x.i
proc test2(x: ptr A) =
echo x.i
x[] = nil
proc test3(x: var A) =
echo x.i
x = nil
var
a: A = A(i: 5)
b: B = B(i: 3, j: 7)
test1(a)
test1(b)
#test2(addr a)
#test2(addr b) # type mismatch: got (ptr B) but expected one of: t.test2(x: ptr A) ### (27)
test3(a)
#test3(A(b)) # isNil(b) [AssertionError] ### (30)
#test3(cast[A](b)) # type mismatch: got (A) but expected one of: t.test3(x: var A)
test3(cast[var A](b)) # llegal storage access. (Attempt to read from nil?)
assert b.isNil
#test3(b) # type mismatch: got (B) but expected one of: t.test3(x: var A) ### (34)
I can understand that lines (27) and (34) do not compile now. Without much thinking one may try to fix line (34) by lines 30, 31 or 32, which obviously all is wrong. This is related to https://github.com/nim-lang/Nim/issues/3449. I think "var h = A(b); test3(h); b = nil" is the workaround for this rare problem.Subtyping is not sound with ptr ptr T (note that the same holds for ref and that var is a hidden pointer). Otherwise the following would compile which is not good.
type
A = ref RootObj
A1 = ref object of A
A2 = ref object of A
proc setter(x: var A) =
x = A2()
var
y: A1
setter(y) # ok, so 'y' points to an A2 afterwards. lovely.