Skip to content

Commit

Permalink
fix #9423 followup #17594: distinct generics now work in VM (#21816)
Browse files Browse the repository at this point in the history
* fix #9423 distinct generics now work in vm

* fixes cpp tests

---------

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
(cherry picked from commit deaf684)
  • Loading branch information
ringabout authored and narimiran committed Jun 19, 2023
1 parent 5577645 commit 04d0716
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 19 deletions.
15 changes: 12 additions & 3 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -1434,27 +1434,36 @@ 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]
if m.kind in {nkDerefExpr, nkHiddenDeref}:
# 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

Expand Down
8 changes: 1 addition & 7 deletions lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 1 addition & 6 deletions lib/std/jsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 25 additions & 1 deletion tests/distinct/tdistinct.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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()
3 changes: 1 addition & 2 deletions tests/stdlib/tjsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 04d0716

Please sign in to comment.