From 82bae34b0662a76a5be6efb4d9bd760cdf687896 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 --- 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 25ff62bcc7ef9..067965469ca13 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -850,7 +850,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: @@ -1416,7 +1416,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = 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] @@ -1424,19 +1424,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 7ccd3c43f572b..b68ddd660490a 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1211,13 +1211,7 @@ macro assignDistinctImpl[T: distinct](dst: var T;jsonNode: JsonNode; jsonPath: v 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 71f438905405d..f17407f20ec8b 100644 --- a/lib/std/jsonutils.nim +++ b/lib/std/jsonutils.nim @@ -222,12 +222,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 d6f9023018996..9acf4c9e545e8 100644 --- a/tests/stdlib/tjsonutils.nim +++ b/tests/stdlib/tjsonutils.nim @@ -61,8 +61,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