Open PMunch opened 3 years ago
I have checked this one and it is not arc specific. typ.n
received by codegen doesn't have all the fields of the struct.
Looks like this problem happens earlier in the recursive type instantiation.
Clearly related to #14387 and #9566.
The real cause is that any is ptr
returns false
, while correct answer is unknown it should not be evaluatable.
The Option
is defined this way:
Option*[T] = object
when T is SomePointer:
val: T
else:
val: T
has: bool
Option[T]
is being analyzed with T
defined as any
in liftParamType
and Option[any] gets reduced to
Option*[T] = object
val: T
has: bool
too early.
@Araq, I need your input on the right approach to fix it
Not sure why you say it isn't ARC specific. It works fine with the default GC, but it appears to evaluate when T is SomePointer
as false (the C code has the has
field in the struct). This misses the optimisation that the pointer is nil
is counted as a None
but it still works. With ARC the field is gone from the struct, but the generation of the option tries to assign this field. So internally it seems to be in disagreement over whether or not T is a pointer.
@PMunch I think for a non-compiler dev it is ARC specific, but for a compiler developer that is misleading as it's not an ARC bug but a type graph bug with different consequences depending on which GC you use.
Ah I see what you mean. So fixing it would mean ARC would work and non-ARC would actually use the pointer is nil
optimisation, both of which I assume have the same underlying cause.
This issue bit me recently in the context of defining a Norm model: https://forum.nim-lang.org/t/8853
maybe similar to https://github.com/nim-lang/Nim/issues/14758
ARC generates bad C code for
Option
of a nested ref type.Example
Current Output
Possible Solution
Not sure what causes this, possibly related to https://github.com/nim-lang/Nim/issues/14387 and https://github.com/nim-lang/Nim/issues/9566, but this only happens for ARC. A workaround is to split the type:
Additional Information