diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 2d9da2f286..10bb1ed23f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -3820,7 +3820,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Builder) var tupleInit: StructInitializer let initKind = if containsOpaqueImportcField(t): siNamedStruct else: siOrderedStruct result.addStructInitializer(tupleInit, kind = initKind): - if p.vccAndC and t.isEmptyTupleType: + if p.vccAndC and validTupleTypeFields(t) == 0: result.addField(tupleInit, name = "dummy"): result.addIntValue(0) for i, a in t.ikids: diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 95b709f226..cd90de6f1b 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1474,35 +1474,38 @@ proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo t.incl tfObjHasKids t = t.baseClass +proc validTupleTypeFields(t: PType): int = + # we want to treat tuples with only void fields as empty, so we need to exclude void types here: + result = 0 + for a in t.kids: + if not isEmptyType(a): inc result + proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) = genTypeInfoAuxBase(m, typ, typ, name, cIntValue(0), info) var expr = getNimNode(m) - if not typ.isEmptyTupleType: - var nonVoidKids = 0 - for a in typ.kids: - if not isEmptyType(a): inc nonVoidKids - if nonVoidKids > 0: - var tmp = getTempName(m) & "_" & $nonVoidKids - genTNimNodeArray(m, tmp, nonVoidKids) - var j = 0 - for i, a in typ.ikids: - # Do not produce code for void types - if isEmptyType(a): continue - var tmp2 = getNimNode(m) - let fieldTypInfo = genTypeInfoV1(m, a, info) - m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(j), cAddr(tmp2)) - m.s[cfsTypeInit3].addFieldAssignment(tmp2, "kind", 1) - m.s[cfsTypeInit3].addFieldAssignmentWithValue(tmp2, "offset"): - m.s[cfsTypeInit3].addOffsetof(getTypeDesc(m, origType, dkVar), "Field" & $i) - m.s[cfsTypeInit3].addFieldAssignment(tmp2, "typ", fieldTypInfo) - m.s[cfsTypeInit3].addFieldAssignment(tmp2, "name", "\"Field" & $i & "\"") - inc j - m.s[cfsTypeInit3].addFieldAssignment(expr, "len", nonVoidKids) - m.s[cfsTypeInit3].addFieldAssignment(expr, "kind", 2) - m.s[cfsTypeInit3].addFieldAssignment(expr, "sons", - cAddr(subscript(tmp, cIntValue(0)))) + let nonVoidKids = validTupleTypeFields(typ) + if nonVoidKids > 0: + var tmp = getTempName(m) & "_" & $nonVoidKids + genTNimNodeArray(m, tmp, nonVoidKids) + var j = 0 + for i, a in typ.ikids: + # Do not produce code for void types + if isEmptyType(a): continue + var tmp2 = getNimNode(m) + let fieldTypInfo = genTypeInfoV1(m, a, info) + m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(j), cAddr(tmp2)) + m.s[cfsTypeInit3].addFieldAssignment(tmp2, "kind", 1) + m.s[cfsTypeInit3].addFieldAssignmentWithValue(tmp2, "offset"): + m.s[cfsTypeInit3].addOffsetof(getTypeDesc(m, origType, dkVar), "Field" & $i) + m.s[cfsTypeInit3].addFieldAssignment(tmp2, "typ", fieldTypInfo) + m.s[cfsTypeInit3].addFieldAssignment(tmp2, "name", "\"Field" & $i & "\"") + inc j + m.s[cfsTypeInit3].addFieldAssignment(expr, "len", nonVoidKids) + m.s[cfsTypeInit3].addFieldAssignment(expr, "kind", 2) + m.s[cfsTypeInit3].addFieldAssignment(expr, "sons", + cAddr(subscript(tmp, cIntValue(0)))) else: - m.s[cfsTypeInit3].addFieldAssignment(expr, "len", typ.kidsLen) + m.s[cfsTypeInit3].addFieldAssignment(expr, "len", cIntValue(0)) m.s[cfsTypeInit3].addFieldAssignment(expr, "kind", 2) m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "node", cAddr(expr))