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.
This commit is contained in:
parent
4572568045
commit
631a8ab57f
3 changed files with 32 additions and 13 deletions
|
|
@ -165,7 +165,6 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
|
||||||
of tySet:
|
of tySet:
|
||||||
if mapSetType(conf, base) == ctArray: result = ctPtrToArray
|
if mapSetType(conf, base) == ctArray: result = ctPtrToArray
|
||||||
else: result = ctPtr
|
else: result = ctPtr
|
||||||
# XXX for some reason this breaks the pegs module
|
|
||||||
else: result = ctPtr
|
else: result = ctPtr
|
||||||
of tyPointer: result = ctPtr
|
of tyPointer: result = ctPtr
|
||||||
of tySequence: result = ctNimSeq
|
of tySequence: result = ctNimSeq
|
||||||
|
|
|
||||||
|
|
@ -196,18 +196,23 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
else:
|
else:
|
||||||
c.hashSym(t.sym)
|
c.hashSym(t.sym)
|
||||||
if {sfAnon, sfGenSym} * t.sym.flags != {}:
|
if {sfAnon, sfGenSym} * t.sym.flags != {}:
|
||||||
# generated object names can be identical, so we need to
|
# Generated object names can be identical, so we need to
|
||||||
# disambiguate furthermore by hashing the field types and names:
|
# disambiguate furthermore by hashing the field types and names.
|
||||||
# mild hack to prevent endless recursions (makes nimforum compile again):
|
if t.n.len > 0:
|
||||||
let oldFlags = t.sym.flags
|
let oldFlags = t.sym.flags
|
||||||
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
|
# Mild hack to prevent endless recursion.
|
||||||
let n = t.n
|
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
|
||||||
for i in 0 ..< n.len:
|
for n in t.n:
|
||||||
assert n[i].kind == nkSym
|
assert(n.kind == nkSym)
|
||||||
let s = n[i].sym
|
let s = n.sym
|
||||||
c.hashSym s
|
c.hashSym s
|
||||||
c.hashType s.typ, flags
|
c.hashType s.typ, flags
|
||||||
t.sym.flags = oldFlags
|
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:
|
else:
|
||||||
c &= t.id
|
c &= t.id
|
||||||
if t.len > 0 and t.sons[0] != nil:
|
if t.len > 0 and t.sons[0] != nil:
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,18 @@ proc foo[T](t: T) =
|
||||||
|
|
||||||
foo(123)
|
foo(123)
|
||||||
foo("baz")
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue