fixes #25509; removes void fields from a named tuple type (#25515)

fixes #25509

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit b51be75613)
This commit is contained in:
ringabout
2026-02-24 17:47:14 +08:00
committed by narimiran
parent bc1b7060b5
commit 8ccba2dc86
2 changed files with 67 additions and 1 deletions

View File

@@ -562,6 +562,26 @@ proc eraseVoidParams*(t: PType) =
setLen t.n.sons, pos
break
proc eraseTupleVoidFields*(t: PType) =
## Remove void fields from a named tuple type, compacting both `t.n`
## (the field symbol nodes) and `t.sonsImpl` (the child types).
if t.n == nil: return # anonymous tuple, nothing to compact
for i in 0..<t.kidsLen:
if t.n[i].kind == nkRecList or t[i].kind == tyVoid:
# found first void field, compact from here
var pos = i
for j in i+1..<t.kidsLen:
if t[j].kind != tyVoid and j < t.n.len and t.n[j].kind != nkRecList:
t.n[pos] = t.n[j]
t[pos] = t[j]
if t.n[pos].kind == nkSym:
t.n[pos].sym.position = pos
inc pos
# else: skip void entries
setLen t.n.sons, pos
t.setSonsLen pos
break
proc skipIntLiteralParams*(t: PType; idgen: IdGenerator) =
for i, p in t.ikids:
if p == nil: continue
@@ -693,7 +713,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
of tyUserTypeClass:
result = t
of tyStatic:
if cl.c.matchedConcept != nil:
# allow concepts to not instantiate statics for now
@@ -766,6 +786,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
propagateFieldFlags(result, result.n)
if result.kind == tyObject and cl.c.computeRequiresInit(cl.c, result):
result.flags.incl tfRequiresInit
if result.kind == tyTuple:
eraseTupleVoidFields(result)
of tyProc:
eraseVoidParams(result)

View File

@@ -131,3 +131,47 @@ static:
main()
mainProc()
block:
type
Tuple[N] = tuple
a: int
b: N
TupleVoid = Tuple[void]
var x: TupleVoid = (a: 1, )
doAssert x.a == 1
block:
type W[N] = seq[tuple[b: N]]
var _: W[void]
block:
type Tuple2[N] = tuple
a: int
b: N
c: int
var y: Tuple2[void] = (a: 10, c: 20)
doAssert y.a == 10
doAssert y.c == 20
block:
type Outer[N] = tuple
inner: tuple[x: int, y: N]
var o: Outer[void] = (inner: (x: 3, ))
doAssert o.inner.x == 3
block:
type Tup[T] = tuple
a: int
b: T
proc f[T](t: Tup[T]): int =
result = t.a
var z: Tup[void] = (a: 7, )
doAssert f(z) == 7