mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
fixes #22669 constructor pragma doesnt init Nim default fields --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -1494,8 +1494,27 @@ proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
|
||||
else:
|
||||
result = false
|
||||
|
||||
|
||||
proc genFieldObjConstr(p: BProc; ty: PType; useTemp, isRef: bool; nField, val, check: PNode; d: var TLoc; r: Rope; info: TLineInfo) =
|
||||
var tmp2: TLoc = default(TLoc)
|
||||
tmp2.r = r
|
||||
let field = lookupFieldAgain(p, ty, nField.sym, tmp2.r)
|
||||
if field.loc.r == "": fillObjectFields(p.module, ty)
|
||||
if field.loc.r == "": internalError(p.config, info, "genFieldObjConstr")
|
||||
if check != nil and optFieldCheck in p.options:
|
||||
genFieldCheck(p, check, r, field)
|
||||
tmp2.r.add(".")
|
||||
tmp2.r.add(field.loc.r)
|
||||
if useTemp:
|
||||
tmp2.k = locTemp
|
||||
tmp2.storage = if isRef: OnHeap else: OnStack
|
||||
else:
|
||||
tmp2.k = d.k
|
||||
tmp2.storage = if isRef: OnHeap else: d.storage
|
||||
tmp2.lode = val
|
||||
expr(p, val, tmp2)
|
||||
|
||||
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
#echo renderTree e, " ", e.isDeepConstExpr
|
||||
# inheritance in C++ does not allow struct initialization so
|
||||
# we skip this step here:
|
||||
if not p.module.compileToCpp and optSeqDestructors notin p.config.globalOptions:
|
||||
@@ -1534,24 +1553,11 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
discard getTypeDesc(p.module, t)
|
||||
let ty = getUniqueType(t)
|
||||
for i in 1..<e.len:
|
||||
let it = e[i]
|
||||
var tmp2: TLoc = default(TLoc)
|
||||
tmp2.r = r
|
||||
let field = lookupFieldAgain(p, ty, it[0].sym, tmp2.r)
|
||||
if field.loc.r == "": fillObjectFields(p.module, ty)
|
||||
if field.loc.r == "": internalError(p.config, e.info, "genObjConstr")
|
||||
if it.len == 3 and optFieldCheck in p.options:
|
||||
genFieldCheck(p, it[2], r, field)
|
||||
tmp2.r.add(".")
|
||||
tmp2.r.add(field.loc.r)
|
||||
if useTemp:
|
||||
tmp2.k = locTemp
|
||||
tmp2.storage = if isRef: OnHeap else: OnStack
|
||||
else:
|
||||
tmp2.k = d.k
|
||||
tmp2.storage = if isRef: OnHeap else: d.storage
|
||||
tmp2.lode = it[1]
|
||||
expr(p, it[1], tmp2)
|
||||
var check: PNode = nil
|
||||
if e[i].len == 3 and optFieldCheck in p.options:
|
||||
check = e[i][2]
|
||||
genFieldObjConstr(p, ty, useTemp, isRef, e[i][0], e[i][1], check, d, r, e.info)
|
||||
|
||||
if useTemp:
|
||||
if d.k == locNone:
|
||||
d = tmp
|
||||
|
||||
@@ -1171,6 +1171,11 @@ proc genProcAux*(m: BModule, prc: PSym) =
|
||||
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
|
||||
elif sfConstructor in prc.flags:
|
||||
fillLoc(resNode.sym.loc, locParam, resNode, "this", OnHeap)
|
||||
let ty = resNode.sym.typ[0] #generate nim's ctor
|
||||
for i in 1..<resNode.sym.ast.len:
|
||||
let field = resNode.sym.ast[i]
|
||||
genFieldObjConstr(p, ty, useTemp = false, isRef = false,
|
||||
field[0], field[1], check = nil, resNode.sym.loc, "(*this)", tmpInfo)
|
||||
else:
|
||||
fillResult(p.config, resNode, prc.typ)
|
||||
assignParam(p, res, prc.typ[0])
|
||||
|
||||
@@ -1711,6 +1711,8 @@ proc addThis(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
||||
c.p.resultSym = s
|
||||
n.add newSymNode(c.p.resultSym)
|
||||
addParamOrResult(c, c.p.resultSym, owner)
|
||||
#resolves nim's obj ctor inside cpp ctors see #22669
|
||||
s.ast = c.semExpr(c, newTree(nkCall, t[0].sym.ast[0]))
|
||||
|
||||
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
||||
template genResSym(s) =
|
||||
|
||||
@@ -7,6 +7,15 @@ discard """
|
||||
123
|
||||
0
|
||||
123
|
||||
___
|
||||
0
|
||||
777
|
||||
10
|
||||
123
|
||||
0
|
||||
777
|
||||
10
|
||||
123
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -73,4 +82,28 @@ proc main =
|
||||
n.x = 123
|
||||
echo n.x
|
||||
|
||||
main()
|
||||
main()
|
||||
#bug:
|
||||
echo "___"
|
||||
type
|
||||
NimClassWithDefault = object
|
||||
x: int
|
||||
y = 777
|
||||
case kind: bool = true
|
||||
of true:
|
||||
z: int = 10
|
||||
else: discard
|
||||
|
||||
proc makeNimClassWithDefault(): NimClassWithDefault {.constructor.} =
|
||||
discard
|
||||
|
||||
proc init =
|
||||
for i in 0 .. 1:
|
||||
var n = makeNimClassWithDefault()
|
||||
echo n.x
|
||||
echo n.y
|
||||
echo n.z
|
||||
n.x = 123
|
||||
echo n.x
|
||||
|
||||
init()
|
||||
Reference in New Issue
Block a user