From 45e21ce8f1f06c8b85f574cb830b429f3997a2e4 Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 12 Nov 2024 16:31:08 +0300 Subject: [PATCH] fix jsonutils macro with generic case object (#24429) split from #24425 The added test did not work previously. The result of `getTypeImpl` is the uninstantiated AST of the original type symbol, and the macro attempts to use this type for the result. To fix the issue, the provided `typedesc` argument is used instead. --- lib/std/jsonutils.nim | 2 +- tests/stdlib/tjsonutils.nim | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/std/jsonutils.nim b/lib/std/jsonutils.nim index 2d28748ce8..a86dd5f900 100644 --- a/lib/std/jsonutils.nim +++ b/lib/std/jsonutils.nim @@ -112,7 +112,7 @@ macro initCaseObject(T: typedesc, fun: untyped): untyped = else: raiseAssert $t.kind # xxx `nnkPtrTy` could be handled too doAssert t2.kind == nnkRecList result = newTree(nnkObjConstr) - result.add sym + result.add T for ti in t2: if ti.kind == nnkRecCase: let key = ti[0][0] diff --git a/tests/stdlib/tjsonutils.nim b/tests/stdlib/tjsonutils.nim index 9acf4c9e54..9d9188d755 100644 --- a/tests/stdlib/tjsonutils.nim +++ b/tests/stdlib/tjsonutils.nim @@ -206,6 +206,19 @@ template fn() = # sanity check: nesting inside a tuple testRoundtrip((Foo[int](x0: 1.5, t1: false, z2: 6), "foo")): """[{"x0":1.5,"t1":false,"z2":6,"x1":""},"foo"]""" + block: # generic case object using generic type + type Foo[T] = ref object + x0: float + case t1: bool + of true: z1: int8 + of false: z2: uint16 + x1: string + x2: T + testRoundtrip(Foo[float](t1: true, z1: 5, x1: "bar", x2: 2.5)): """{"x0":0.0,"t1":true,"z1":5,"x1":"bar","x2":2.5}""" + testRoundtrip(Foo[int](x0: 1.5, t1: false, z2: 6, x2: 2)): """{"x0":1.5,"t1":false,"z2":6,"x1":"","x2":2}""" + # sanity check: nesting inside a tuple + testRoundtrip((Foo[int](x0: 1.5, t1: false, z2: 6, x2: 2), "foo")): """[{"x0":1.5,"t1":false,"z2":6,"x1":"","x2":2},"foo"]""" + block: # case object: 2 discriminants, `when` branch, range discriminant type Foo[T] = object case t1: bool