Skip to content

Commit fd3c84a

Browse files
committed
fix wrong hooks being picked for tuple types
Summary ======= * fix tuples such as `((A, B),)` and `((A,), B)` being assigned the the same set of hooks * fix the aforementioned tuples sharing the same RTTI object Details ======= * add the tuple length to the type representation during type hashing (`sighash`), so that `((A,), B)` and `((A,), B)` result in two different `SigHash`es * `liftdestructors` uses `sighashes` for canonicalizing structural types, thus previously treating said tuples as the same type * RTTI creation, which also uses `SigHash`, was affected in the same way
1 parent 39660ca commit fd3c84a

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

compiler/sem/sighashes.nim

+3
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
188188
c.hashTree(t.n, {})
189189
of tyTuple:
190190
c &= char(t.kind)
191+
# add the length so that (int, int) and ((int,), int) have different
192+
# representations
193+
c &= t.len
191194
if t.n != nil and CoType notin flags:
192195
assert(t.n.len == t.len)
193196
for i in 0..<t.n.len:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
discard """
2+
description: '''
3+
Ensure that hook synthesis considers ``(A, (B, C))`` different from
4+
``(A, (B,), C)``.
5+
'''
6+
output: "3\n4\n1\n2\n"
7+
knownIssue.js vm: "seq destructors don't work yet"
8+
"""
9+
10+
type Object = object
11+
val: int
12+
13+
proc `=destroy`(x: var Object) =
14+
echo x.val
15+
16+
# a seq is only used for testing purposes, since it caused misbehaviour at
17+
# run-time. Using ``(Object, (Object,) Object)`` and
18+
# ``(Object, (Object, Object))`` also led to the same issue, but ran
19+
# "correctly" due to both types having the same in-memory layout
20+
type
21+
Tup1 = (seq[(Object,)], Object)
22+
Tup2 = (seq[(Object, Object)],)
23+
24+
proc test() =
25+
var x: Tup1 = (@[(Object(val: 1),)], Object(val: 2))
26+
var y: Tup2 = (@[(Object(val: 3), Object(val: 4))],)
27+
# both locations were treated as having type `Tup1` by the called
28+
# destructor, resulting in either crashes or the wrong output being produced
29+
30+
test()

0 commit comments

Comments
 (0)