Fix #25883 tuple sighash collision (#25889)

fixes #25886
fixes #25883

See #25883 

Tuples only hash leaves so if 2 tuples have the same flattened
representation they collide in the C codegen.

Fix by hashing the length as well to disambiguate nesting levels.

---------

Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
This commit is contained in:
Mamy Ratsimbazafy
2026-07-09 15:47:58 +02:00
committed by GitHub
parent b290be8d83
commit e50fafc971
2 changed files with 46 additions and 0 deletions

View File

@@ -274,6 +274,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: Confi
c.hashTree(t.n, {}, conf)
of tyTuple:
c &= char(t.kind)
c &= t.len
if t.n != nil and CoType notin flags:
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)

View File

@@ -0,0 +1,45 @@
discard """
targets: "c cpp"
output: "13"
"""
# bug #25883: C codegen assigns same type hash to tuples with different nesting
# but identical flattened content.
# ((Int[1], Int[2]), Int[13], Int[14]) and ((Int[1], Int[2], Int[13]), Int[14])
# must get distinct C type names.
type
Int[V: static int] = object
proc main() =
var b = ((1, 2), 13, 14)
var c = ((1, 2, 13), 14)
echo c[0][2]
main()
block:
type
Int[V: static int] = object
Layout[Sh, St] = object
shape: Sh
stride: St
func makeB(): auto =
Layout[((Int[2], Int[3]), Int[5], Int[7]), ((Int[1], Int[2]), Int[6], Int[30])](
shape: ((Int[2](), Int[3]()), Int[5](), Int[7]()),
stride: ((Int[1](), Int[2]()), Int[6](), Int[30]())
)
func makeC(): auto =
Layout[((Int[2], Int[3], Int[5]), Int[7]), ((Int[1], Int[2], Int[6]), Int[30])](
shape: ((Int[2](), Int[3](), Int[5]()), Int[7]()),
stride: ((Int[1](), Int[2](), Int[6]()), Int[30]())
)
proc main() =
let b = makeB()
let c = makeC()
main()