New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option causes a crash on distinct ref types #9566
Comments
A workaround to my initial issue is to do something like this: import json
import options
type
TestTypeObj = distinct JsonNodeObj
TestType = ref TestTypeObj
var somelongname: Option[JsonNode]
var anotherlongname: Option[TestType]
if anotherlongname.isNone:
echo "as expected" This will allow |
I gave this issue a shot today, but I was not succesful. This is what I tried: import typetraits, macros
macro isSomePointer(t: typedesc): bool =
var impl = t.getTypeInst[1].getTypeImpl
if impl.kind == nnkDistinctTy:
impl = impl[0].getTypeImpl
if impl.kind in {nnkPtrTy,nnkRefTy}:
result = newLit(true)
elif impl.kind == nnkSym and impl.eqIdent("pointer"):
result = newLit(true)
else:
result = newLit(false)
type
Option*[T] = object
## An optional type that stores its value and state separately in a boolean.
when isSomePointer(T):
val: T
else:
val: T
has: bool
UnpackError* = object of Defect The problem is, the macro is not resolved, when the generic is instantiated, it is resolved immediately and the |
This still produces a codegen error. |
Noticed a very strange bug with options and distinct types (not that I think the source of the issue is related to either). The supplied example throws an error unless
-d:passTest
is passed when compiling. The error comes from the C compiler which complains that a struct doesn't have the fieldhas
. The options module tries to optimise options ofref | ptr | pointer
to just be a nil check instead of having a separatehas
field. Nim appears to not see thedistinct JsonNode
as aref
type, but it is able to see thatOption[TestType]
should be the same as aOption[JsonNode]
. This means that ifsomelongname
(named to be easy to search for in the C source) is defined beforeanotherlongname
then the resultingOption
struct doesn't have a has field asJsonNode
is a ref type. But if the order is different, or ifsomelongname
is not defined at all, then the resultingOption
struct has the field as it doesn't seeTestType
as aref
.Example
Current Output
Without
-d:passTest
With
-d:passTest
Additional Information
I ran into this when trying to use my jsonschema library to create nimlsp, and managed to condense the error down to this.
EDIT: Found smaller example and probable root cause (updated example above).
EDIT2:
After some more testing I found out that this is the issue:
This will output "MyRefType is ref", but not "TestType is ref". But Nim is still able to see that these are the same type, meaning that things like the option will be reused, but the two types will behave differently.
The text was updated successfully, but these errors were encountered: