mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
* fixes #12015 by also checking kind of `typeNode` If a tuple field is aliased it'll appear the same as a ref type in a call to `getType` if only for the kind of the resulting `NimNode` is checked (that is a `nnkBracketExpr`) * fix test case due to #12017 and add more realistic test case Adds an additional test case, which includes generics and is closer to the real failure I encountered * remove previous fix and fix differently after all The previous fix was incomplete, because it failed for generics. Note that the `of "tuple"` is not actually needed, the `nnkBracketExpr` branch in the `else` branch would catch it too, but I decided to introduce it for clarity. However, the latter is actually needed, because it seems for aliases of `seq` we end up in it. * update comment about global `%` proc in json test
This commit is contained in:
@@ -1369,11 +1369,20 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||
for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`;
|
||||
list
|
||||
)
|
||||
|
||||
of "tuple":
|
||||
let typeNode = getTypeImpl(typeSym)
|
||||
result = createConstructor(typeNode, jsonNode)
|
||||
else:
|
||||
# Generic type.
|
||||
# Generic type or some `seq[T]` alias
|
||||
let obj = getType(typeSym)
|
||||
result = processType(typeSym, obj, jsonNode, false)
|
||||
case obj.kind
|
||||
of nnkBracketExpr:
|
||||
# probably a `seq[T]` alias
|
||||
let typeNode = getTypeImpl(typeSym)
|
||||
result = createConstructor(typeNode, jsonNode)
|
||||
else:
|
||||
# generic type
|
||||
result = processType(typeSym, obj, jsonNode, false)
|
||||
of nnkSym:
|
||||
# Handle JsonNode.
|
||||
if ($typeSym).cmpIgnoreStyle("jsonnode") == 0:
|
||||
@@ -1385,7 +1394,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||
if typeNode.typeKind == ntyDistinct:
|
||||
result = createConstructor(typeNode, jsonNode)
|
||||
elif obj.kind == nnkBracketExpr:
|
||||
# When `Sym "Foo"` turns out to be a `ref object`.
|
||||
# When `Sym "Foo"` turns out to be a `ref object` or `tuple`
|
||||
result = createConstructor(obj, jsonNode)
|
||||
else:
|
||||
result = processType(typeSym, obj, jsonNode, false)
|
||||
|
||||
@@ -517,6 +517,42 @@ when true:
|
||||
doAssert v.name == "smith"
|
||||
doAssert MyRef(w).name == "smith"
|
||||
|
||||
# bug #12015
|
||||
# The definition of the `%` proc needs to be here, since the `% c` calls below
|
||||
# can only find our custom `%` proc for `Pix` if defined in global scope.
|
||||
type
|
||||
Pix = tuple[x, y: uint8, ch: uint16]
|
||||
proc `%`(p: Pix): JsonNode =
|
||||
result = %* { "x" : % p.x,
|
||||
"y" : % p.y,
|
||||
"ch" : % p.ch }
|
||||
block:
|
||||
type
|
||||
Cluster = object
|
||||
works: tuple[x, y: uint8, ch: uint16] # working
|
||||
fails: Pix # previously broken
|
||||
|
||||
let data = (x: 123'u8, y: 53'u8, ch: 1231'u16)
|
||||
let c = Cluster(works: data, fails: data)
|
||||
let cFromJson = (% c).to(Cluster)
|
||||
doAssert c == cFromJson
|
||||
|
||||
block:
|
||||
# bug related to #12015
|
||||
type
|
||||
PixInt = tuple[x, y, ch: int]
|
||||
SomePix = Pix | PixInt
|
||||
Cluster[T: SomePix] = seq[T]
|
||||
ClusterObject[T: SomePix] = object
|
||||
data: Cluster[T]
|
||||
RecoEvent[T: SomePix] = object
|
||||
cluster: seq[ClusterObject[T]]
|
||||
|
||||
let data = @[(x: 123'u8, y: 53'u8, ch: 1231'u16)]
|
||||
var c = RecoEvent[Pix](cluster: @[ClusterObject[Pix](data: data)])
|
||||
let cFromJson = (% c).to(RecoEvent[Pix])
|
||||
doAssert c == cFromJson
|
||||
|
||||
# TODO: when the issue with the limeted vm registers is solved, the
|
||||
# exact same test as above should be evaluated at compile time as
|
||||
# well, to ensure that the vm functionality won't diverge from the
|
||||
|
||||
Reference in New Issue
Block a user