mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-14 15:23:27 +00:00
Fix edge case in type hashing (#10601) [backport]
Empty types introduced by a template produced the same hash of the
"clean" type sharing the same name.
(cherry picked from commit 631a8ab57f)
This commit is contained in:
@@ -165,7 +165,6 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
|
||||
of tySet:
|
||||
if mapSetType(conf, base) == ctArray: result = ctPtrToArray
|
||||
else: result = ctPtr
|
||||
# XXX for some reason this breaks the pegs module
|
||||
else: result = ctPtr
|
||||
of tyPointer: result = ctPtr
|
||||
of tySequence: result = ctNimSeq
|
||||
|
||||
@@ -196,18 +196,23 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||
else:
|
||||
c.hashSym(t.sym)
|
||||
if {sfAnon, sfGenSym} * t.sym.flags != {}:
|
||||
# generated object names can be identical, so we need to
|
||||
# disambiguate furthermore by hashing the field types and names:
|
||||
# mild hack to prevent endless recursions (makes nimforum compile again):
|
||||
let oldFlags = t.sym.flags
|
||||
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
|
||||
let n = t.n
|
||||
for i in 0 ..< n.len:
|
||||
assert n[i].kind == nkSym
|
||||
let s = n[i].sym
|
||||
c.hashSym s
|
||||
c.hashType s.typ, flags
|
||||
t.sym.flags = oldFlags
|
||||
# Generated object names can be identical, so we need to
|
||||
# disambiguate furthermore by hashing the field types and names.
|
||||
if t.n.len > 0:
|
||||
let oldFlags = t.sym.flags
|
||||
# Mild hack to prevent endless recursion.
|
||||
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
|
||||
for n in t.n:
|
||||
assert(n.kind == nkSym)
|
||||
let s = n.sym
|
||||
c.hashSym s
|
||||
c.hashType s.typ, flags
|
||||
t.sym.flags = oldFlags
|
||||
else:
|
||||
# The object has no fields: we _must_ add something here in order to
|
||||
# make the hash different from the one we produce by hashing only the
|
||||
# type name.
|
||||
c &= ".empty"
|
||||
else:
|
||||
c &= t.id
|
||||
if t.len > 0 and t.sons[0] != nil:
|
||||
|
||||
@@ -8,3 +8,18 @@ proc foo[T](t: T) =
|
||||
|
||||
foo(123)
|
||||
foo("baz")
|
||||
|
||||
# Empty type in template is correctly disambiguated
|
||||
block:
|
||||
template foo() =
|
||||
type M = object
|
||||
discard
|
||||
var y = M()
|
||||
|
||||
foo()
|
||||
|
||||
type M = object
|
||||
x: int
|
||||
|
||||
var x = M(x: 1)
|
||||
doAssert(x.x == 1)
|
||||
|
||||
Reference in New Issue
Block a user