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 <timothee.cour2@gmail.com>
This commit is contained in:
ringabout
2023-05-10 17:06:14 +08:00
committed by GitHub
parent 4b76037e5f
commit deaf684375
5 changed files with 40 additions and 19 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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