diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index ade2cb41ff..95a7beada5 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2158,17 +2158,72 @@ proc genNamedConstExpr(p: BProc, n: PNode): Rope = if n.kind == nkExprColonExpr: result = genConstExpr(p, n.sons[1]) else: result = genConstExpr(p, n) +proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope = + var t = skipTypes(typ, abstractRange-{tyTypeDesc}) + case t.kind + of tyBool: result = rope"NIM_FALSE" + of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result = rope"0" + of tyFloat..tyFloat128: result = rope"0.0" + of tyCString, tyString, tyVar, tyPointer, tyPtr, tySequence, tyExpr, + tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil: + result = rope"NIM_NIL" + of tyProc: + if t.callConv != ccClosure: + result = rope"NIM_NIL" + else: + result = rope"{NIM_NIL, NIM_NIL}" + of tyObject: + if not isObjLackingTypeField(t) and not p.module.compileToCpp: + result = "{{$1}}" % [genTypeInfo(p.module, t)] + else: + result = rope"{}" + of tyArray, tyTuple: result = rope"{}" + of tySet: + if mapType(t) == ctArray: result = rope"{}" + else: result = rope"0" + else: + globalError(info, "cannot create null element for: " & $t.kind) + +proc getNullValueAux(p: BProc; obj, cons: PNode, result: var Rope) = + case obj.kind + of nkRecList: + for i in countup(0, sonsLen(obj) - 1): getNullValueAux(p, obj.sons[i], cons, result) + of nkRecCase: + getNullValueAux(p, obj.sons[0], cons, result) + for i in countup(1, sonsLen(obj) - 1): + getNullValueAux(p, lastSon(obj.sons[i]), cons, result) + of nkSym: + if not result.isNil: result.add ", " + let field = obj.sym + for i in 1.. 1: add(result, ",") - for i in countup(ord(n.kind == nkObjConstr), length - 2): + for i in countup(0, length - 2): addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])]) - if length > ord(n.kind == nkObjConstr): + if length > 0: add(result, genNamedConstExpr(p, n.sons[length - 1])) addf(result, "}$n", []) @@ -2203,12 +2258,14 @@ proc genConstExpr(p: BProc, n: PNode): Rope = var cs: TBitSet toBitSet(n, cs) result = genRawSetData(cs, int(getSize(n.typ))) - of nkBracket, nkPar, nkClosure, nkObjConstr: + of nkBracket, nkPar, nkClosure: var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: result = genConstSeq(p, n, n.typ) else: result = genConstSimpleList(p, n) + of nkObjConstr: + result = genConstObjConstr(p, n) else: var d: TLoc initLocExpr(p, n, d) diff --git a/tests/ccgbugs/tobjconstr_outoforder.nim b/tests/ccgbugs/tobjconstr_outoforder.nim new file mode 100644 index 0000000000..846a753d5e --- /dev/null +++ b/tests/ccgbugs/tobjconstr_outoforder.nim @@ -0,0 +1,38 @@ +discard """ + output: '''(left: 1, up: 0, right: 2, down: 0) +(left: 0, up: 1, right: 0, down: 2) +@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)] +@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)] +true''' +""" + +# bug #5339 +type + Dirs = object + left: int + up: int + right: int + down: int + +let + a = Dirs( + left: 1, + right: 2, + ) + b = Dirs( + up: 1, + down: 2, + ) + works = @[ + a, + b, + ] + fails = @[ + Dirs(left: 1, right: 2), + Dirs(up: 1, down: 2), + ] +echo a +echo b +echo works +echo fails +echo works == fails