Fixes #10005
This commit is contained in:
parent
b53327c92a
commit
19f5835d5c
2 changed files with 33 additions and 33 deletions
|
|
@ -918,35 +918,15 @@ proc countJsParams(typ: PType): int =
|
||||||
const
|
const
|
||||||
nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||||
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkStringToCString,
|
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkStringToCString,
|
||||||
|
nkObjConstr, nkTupleConstr, nkBracket,
|
||||||
nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix,
|
nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix,
|
||||||
nkCommand, nkHiddenCallConv, nkCallStrLit}
|
nkCommand, nkHiddenCallConv, nkCallStrLit}
|
||||||
|
|
||||||
proc needsNoCopy(p: PProc; y: PNode): bool =
|
proc needsNoCopy(p: PProc; y: PNode): bool =
|
||||||
# if the node is a literal object constructor we have to recursively
|
return y.kind in nodeKindsNeedNoCopy or
|
||||||
# check the expressions passed into it
|
(mapType(y.typ) != etyBaseIndex and
|
||||||
case y.kind
|
|
||||||
of nkObjConstr:
|
|
||||||
for arg in y.sons[1..^1]:
|
|
||||||
if not needsNoCopy(p, arg[1]):
|
|
||||||
return false
|
|
||||||
of nkTupleConstr:
|
|
||||||
for arg in y.sons:
|
|
||||||
var arg = arg
|
|
||||||
if arg.kind == nkExprColonExpr:
|
|
||||||
arg = arg[1]
|
|
||||||
if not needsNoCopy(p, arg):
|
|
||||||
return false
|
|
||||||
of nkBracket:
|
|
||||||
for arg in y.sons:
|
|
||||||
if not needsNoCopy(p, arg):
|
|
||||||
return false
|
|
||||||
of nodeKindsNeedNoCopy:
|
|
||||||
return true
|
|
||||||
else:
|
|
||||||
return (mapType(y.typ) != etyBaseIndex and
|
|
||||||
(skipTypes(y.typ, abstractInst).kind in
|
(skipTypes(y.typ, abstractInst).kind in
|
||||||
{tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes))
|
{tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes))
|
||||||
return true
|
|
||||||
|
|
||||||
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
var a, b: TCompRes
|
var a, b: TCompRes
|
||||||
|
|
@ -2005,6 +1985,10 @@ proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if a.typ == etyBaseIndex:
|
if a.typ == etyBaseIndex:
|
||||||
addf(r.res, "[$1, $2]", [a.address, a.res])
|
addf(r.res, "[$1, $2]", [a.address, a.res])
|
||||||
else:
|
else:
|
||||||
|
if not needsNoCopy(p, n[i]):
|
||||||
|
let typ = n[i].typ.skipTypes(abstractInst)
|
||||||
|
useMagic(p, "nimCopy")
|
||||||
|
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
||||||
add(r.res, a.res)
|
add(r.res, a.res)
|
||||||
add(r.res, "]")
|
add(r.res, "]")
|
||||||
|
|
||||||
|
|
@ -2017,9 +2001,13 @@ proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
if it.kind == nkExprColonExpr: it = it.sons[1]
|
if it.kind == nkExprColonExpr: it = it.sons[1]
|
||||||
gen(p, it, a)
|
gen(p, it, a)
|
||||||
|
let typ = it.typ.skipTypes(abstractInst)
|
||||||
if a.typ == etyBaseIndex:
|
if a.typ == etyBaseIndex:
|
||||||
addf(r.res, "Field$#: [$#, $#]", [i.rope, a.address, a.res])
|
addf(r.res, "Field$#: [$#, $#]", [i.rope, a.address, a.res])
|
||||||
else:
|
else:
|
||||||
|
if not needsNoCopy(p, it):
|
||||||
|
useMagic(p, "nimCopy")
|
||||||
|
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
||||||
addf(r.res, "Field$#: $#", [i.rope, a.res])
|
addf(r.res, "Field$#: $#", [i.rope, a.res])
|
||||||
r.res.add("}")
|
r.res.add("}")
|
||||||
|
|
||||||
|
|
@ -2039,17 +2027,12 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
fieldIDs.incl(f.id)
|
fieldIDs.incl(f.id)
|
||||||
|
|
||||||
let typ = val.typ.skipTypes(abstractInst)
|
let typ = val.typ.skipTypes(abstractInst)
|
||||||
if (typ.kind in IntegralTypes+{tyCstring, tyRef, tyPtr} and
|
|
||||||
mapType(p, typ) != etyBaseIndex) or
|
|
||||||
a.typ == etyBaseIndex or
|
|
||||||
needsNoCopy(p, it.sons[1]):
|
|
||||||
discard
|
|
||||||
else:
|
|
||||||
useMagic(p, "nimCopy")
|
|
||||||
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
|
||||||
if a.typ == etyBaseIndex:
|
if a.typ == etyBaseIndex:
|
||||||
addf(initList, "$#: [$#, $#]", [f.loc.r, a.address, a.res])
|
addf(initList, "$#: [$#, $#]", [f.loc.r, a.address, a.res])
|
||||||
else:
|
else:
|
||||||
|
if not needsNoCopy(p, val):
|
||||||
|
useMagic(p, "nimCopy")
|
||||||
|
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
|
||||||
addf(initList, "$#: $#", [f.loc.r, a.res])
|
addf(initList, "$#: $#", [f.loc.r, a.res])
|
||||||
let t = skipTypes(n.typ, abstractInst + skipPtrs)
|
let t = skipTypes(n.typ, abstractInst + skipPtrs)
|
||||||
createObjInitList(p, t, fieldIDs, initList)
|
createObjInitList(p, t, fieldIDs, initList)
|
||||||
|
|
|
||||||
|
|
@ -54,3 +54,20 @@ let test2 = test1
|
||||||
|
|
||||||
echo toJSON(test1)
|
echo toJSON(test1)
|
||||||
echo toJSON(test2)
|
echo toJSON(test2)
|
||||||
|
|
||||||
|
block issue10005:
|
||||||
|
type
|
||||||
|
Player = ref object of RootObj
|
||||||
|
id*: string
|
||||||
|
nickname*: string
|
||||||
|
color*: string
|
||||||
|
|
||||||
|
proc newPlayer(nickname: string, color: string): Player =
|
||||||
|
let pl = Player(color: "#123", nickname: nickname)
|
||||||
|
return Player(
|
||||||
|
id: "foo",
|
||||||
|
nickname: nickname,
|
||||||
|
color: color,
|
||||||
|
)
|
||||||
|
|
||||||
|
doAssert newPlayer("foo", "#1232").nickname == "foo"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue