From 5daa18684503211a4d65b08fbf1d08d3b1a4748f Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Fri, 6 Mar 2026 06:08:51 +0800 Subject: [PATCH] fix #25508; ignores void types in the backends (#25550) fix #25508 (cherry picked from commit e4b1d8eebcbb176ad0dad509b5b0039fe10de287) --- compiler/ccgexprs.nim | 8 ++++++++ compiler/ccgtypes.nim | 25 +++++++++++++++++++------ compiler/jsgen.nim | 6 +++++- tests/typerel/tvoid.nim | 5 +++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b3d95b67f3..614ac684ae 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -237,6 +237,8 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = flags let t = skipTypes(dest.t, abstractInst).getUniqueType() for i, t in t.ikids: + # Do not produce code for void types + if isEmptyType(t): continue let field = "Field$1" % [i.rope] genAssignment(p, optAsgnLoc(dest, t, field), optAsgnLoc(src, t, field), newflags) @@ -2735,6 +2737,8 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = for i in 0.. 0: result.add ", " getDefaultValue(p, a, info, result) result.add "}" @@ -3391,6 +3397,8 @@ proc genConstTuple(p: BProc, n: PNode; isConst: bool; tup: PType; result: var Ro if p.vccAndC and n.len == 0: result.add "0" for i in 0.. 0: result.add ",\n" if it.kind == nkExprColonExpr: genBracedInit(p, it[1], isConst, tup[i], result) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 996f542579..ff8f8753b9 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -811,6 +811,8 @@ proc getTupleDesc(m: BModule; typ: PType, name: Rope, result = newBuilder("") result.addStruct(m, typ, name, ""): for i, a in typ.ikids: + # Do not produce code for void types + if isEmptyType(a): continue result.addField( name = "Field" & $i, typ = getTypeDescAux(m, a, check, dkField)) @@ -1423,25 +1425,36 @@ proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo t.flags.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, rope("0"), info) var expr = getNimNode(m) - if not typ.isEmptyTupleType: - var tmp = getTempName(m) & "_" & $typ.kidsLen - genTNimNodeArray(m, tmp, rope(typ.kidsLen)) + let nonVoidKids = validTupleTypeFields(typ) + if nonVoidKids > 0: + var tmp = getTempName(m) & "_" & $nonVoidKids + genTNimNodeArray(m, tmp, rope(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) - m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(i), tmp2]) + m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(j), tmp2]) m.s[cfsTypeInit3].addf("$1.kind = 1;$n" & "$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" & "$1.name = \"Field$3\";$n", [tmp2, getTypeDesc(m, origType, dkVar), rope(i), genTypeInfoV1(m, a, info)]) + inc j m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", - [expr, rope(typ.kidsLen), tmp]) + [expr, rope(nonVoidKids), tmp]) else: m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2;$n", - [expr, rope(typ.kidsLen)]) + [expr, rope("0")]) m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), expr]) proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) = diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 8f966b7dd1..ed2452241e 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -2004,8 +2004,12 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = if indirect: result = "[$1]" % [result] of tyTuple: result = rope("{") + var first = true for i in 0.. 0: result.add(", ") + # Do not produce code for void types + if isEmptyType(t[i]): continue + if not first: result.add(", ") + first = false result.addf("Field$1: $2", [i.rope, createVar(p, t[i], false)]) result.add("}") diff --git a/tests/typerel/tvoid.nim b/tests/typerel/tvoid.nim index 8bb5691b88..e00f34168d 100644 --- a/tests/typerel/tvoid.nim +++ b/tests/typerel/tvoid.nim @@ -4,6 +4,7 @@ empty he, no return type; abc a string ha''' + target: "c js" """ proc ReturnT[T](x: T): T = @@ -96,3 +97,7 @@ block: # typeof(stmt) block: template bad2 = echo (nonexistent; discard) doAssert not compiles(bad2()) + +block: + discard default(tuple[b: void]) + discard default((void,))