From 04d0716f37409079642d1350c927370dfb5ed736 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 10 May 2023 17:06:14 +0800 Subject: [PATCH] fix #9423 followup #17594: distinct generics now work in VM (#21816) * fix #9423 distinct generics now work in vm * fixes cpp tests --------- Co-authored-by: Timothee Cour (cherry picked from commit deaf6843752112cfaadc688302c94779d633c686) --- compiler/vmgen.nim | 15 ++++++++++++--- lib/pure/json.nim | 8 +------- lib/std/jsonutils.nim | 7 +------ tests/distinct/tdistinct.nim | 26 +++++++++++++++++++++++++- tests/stdlib/tjsonutils.nim | 3 +-- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index b3576592c1ead..ef6f888c0e392 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -852,7 +852,7 @@ proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = let targ2 = arg.typ.skipTypes({tyDistinct}) proc implicitConv(): bool = - if sameType(t2, targ2): return true + if sameBackendType(t2, targ2): return true # xxx consider whether to use t2 and targ2 here if n.typ.kind == arg.typ.kind and arg.typ.kind == tyProc: # don't do anything for lambda lifting conversions: @@ -1434,7 +1434,7 @@ proc genMarshalStore(c: PCtx, n: PNode, dest: var TDest) = proc unneededIndirection(n: PNode): bool = n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef -proc canElimAddr(n: PNode): PNode = +proc canElimAddr(n: PNode; idgen: IdGenerator): PNode = case n[0].kind of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64: var m = n[0][0] @@ -1442,19 +1442,28 @@ proc canElimAddr(n: PNode): PNode = # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) result = copyNode(n[0]) result.add m[0] + if n.typ.skipTypes(abstractVar).kind != tyOpenArray: + result.typ = n.typ + elif n.typ.skipTypes(abstractInst).kind in {tyVar}: + result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, idgen) of nkHiddenStdConv, nkHiddenSubConv, nkConv: var m = n[0][1] if m.kind in {nkDerefExpr, nkHiddenDeref}: # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) result = copyNode(n[0]) + result.add n[0][0] result.add m[0] + if n.typ.skipTypes(abstractVar).kind != tyOpenArray: + result.typ = n.typ + elif n.typ.skipTypes(abstractInst).kind in {tyVar}: + result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, idgen) else: if n[0].kind in {nkDerefExpr, nkHiddenDeref}: # addr ( deref ( x )) --> x result = n[0][0] proc genAddr(c: PCtx, n: PNode, dest: var TDest, flags: TGenFlags) = - if (let m = canElimAddr(n); m != nil): + if (let m = canElimAddr(n, c.idgen); m != nil): gen(c, m, dest, flags) return diff --git a/lib/pure/json.nim b/lib/pure/json.nim index b22dd4bf768ab..75e3a9359c9ca 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1209,13 +1209,7 @@ when defined(nimFixedForwardGeneric): let baseTyp = typImpl[0] result = quote do: - when nimvm: - # workaround #12282 - var tmp: `baseTyp` - initFromJson( tmp, `jsonNode`, `jsonPath`) - `dst` = `typInst`(tmp) - else: - initFromJson( `baseTyp`(`dst`), `jsonNode`, `jsonPath`) + initFromJson(`baseTyp`(`dst`), `jsonNode`, `jsonPath`) proc initFromJson[T: distinct](dst: var T; jsonNode: JsonNode; jsonPath: var string) = assignDistinctImpl(dst, jsonNode, jsonPath) diff --git a/lib/std/jsonutils.nim b/lib/std/jsonutils.nim index 82458c089934b..3de558320421e 100644 --- a/lib/std/jsonutils.nim +++ b/lib/std/jsonutils.nim @@ -232,12 +232,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) = elif T is uint|uint64: a = T(to(b, uint64)) elif T is Ordinal: a = cast[T](to(b, int)) elif T is pointer: a = cast[pointer](to(b, int)) - elif T is distinct: - when nimvm: - # bug, potentially related to https://github.com/nim-lang/Nim/issues/12282 - a = T(jsonTo(b, distinctBase(T))) - else: - a.distinctBase.fromJson(b) + elif T is distinct: a.distinctBase.fromJson(b) elif T is string|SomeNumber: a = to(b,T) elif T is cstring: case b.kind diff --git a/tests/distinct/tdistinct.nim b/tests/distinct/tdistinct.nim index 8ec0830208106..b6ba7aa993510 100644 --- a/tests/distinct/tdistinct.nim +++ b/tests/distinct/tdistinct.nim @@ -159,7 +159,7 @@ block: #17322 type Foo = distinct string -template main() = +proc main() = # proc instead of template because of MCS/UFCS. # xxx put everything here to test under RT + VM block: # bug #12282 block: @@ -199,5 +199,29 @@ template main() = var c: B + block: # bug #9423 + block: + type Foo = seq[int] + type Foo2 = distinct Foo + template fn() = + var a = Foo2(@[1]) + a.Foo.add 2 + doAssert a.Foo == @[1, 2] + fn() + + block: + type Stack[T] = distinct seq[T] + proc newStack[T](): Stack[T] = + Stack[T](newSeq[T]()) + proc push[T](stack: var Stack[T], elem: T) = + seq[T](stack).add(elem) + proc len[T](stack: Stack[T]): int = + seq[T](stack).len + proc fn() = + var stack = newStack[int]() + stack.push(5) + doAssert stack.len == 1 + fn() + static: main() main() diff --git a/tests/stdlib/tjsonutils.nim b/tests/stdlib/tjsonutils.nim index cb70be4deffa4..fc8f071648dca 100644 --- a/tests/stdlib/tjsonutils.nim +++ b/tests/stdlib/tjsonutils.nim @@ -59,8 +59,7 @@ template fn() = testRoundtrip(pointer(nil)): """0""" testRoundtrip(cast[pointer](nil)): """0""" - # causes workaround in `fromJson` potentially related to - # https://github.com/nim-lang/Nim/issues/12282 + # refs bug #9423 testRoundtrip(Foo(1.5)): """1.5""" block: # OrderedTable