From af66258dca695d932e76ea31bdee2b2f185139cb Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 21 Jun 2018 22:21:24 +0200 Subject: Discriminate gensym'd type names in sigHash The root cause of #7905 lies in the codegen phase. The two template instantiations generate two different MyType types with different members but same t.sym.name leading the caching mechanism to confuse the two. Fixes #7905 --- compiler/sighashes.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'compiler') diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 0b95387cd..720d1848d 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -189,10 +189,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = c.hashTypeSym(t.sym) else: c.hashSym(t.sym) - if sfAnon in t.sym.flags: + 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 wasAnon = sfAnon in t.sym.flags excl t.sym.flags, sfAnon let n = t.n for i in 0 ..< n.len: @@ -200,7 +201,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = let s = n[i].sym c.hashSym s c.hashType s.typ, flags - incl t.sym.flags, sfAnon + if wasAnon: + incl t.sym.flags, sfAnon else: c &= t.id if t.len > 0 and t.sons[0] != nil: -- cgit 1.4.1-2-gfad0 From e39baf46fc523245a7d73b263808b944c6f225db Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 22 Jun 2018 15:09:35 +0200 Subject: Don't blow up with recursive objects --- compiler/sighashes.nim | 7 +++---- tests/types/t7905.nim | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'compiler') diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 720d1848d..0bf2b8459 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -193,16 +193,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = # 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 wasAnon = sfAnon in t.sym.flags - excl t.sym.flags, sfAnon + 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 - if wasAnon: - incl t.sym.flags, sfAnon + t.sym.flags = oldFlags else: c &= t.id if t.len > 0 and t.sons[0] != nil: diff --git a/tests/types/t7905.nim b/tests/types/t7905.nim index ddb371039..ef75bb86c 100644 --- a/tests/types/t7905.nim +++ b/tests/types/t7905.nim @@ -2,6 +2,8 @@ discard """ output: ''' (member: "hello world") (member: 123.456) +(member: "hello world", x: ...) +(member: 123.456, x: ...) ''' """ @@ -16,3 +18,16 @@ template foobar(arg: typed): untyped = foobar("hello world") foobar(123.456'f64) + +template foobarRec(arg: typed): untyped = + type + MyType = object + member: type(arg) + x: ref MyType + + var myVar: MyType + myVar.member = arg + echo myVar + +foobarRec("hello world") +foobarRec(123.456'f64) -- cgit 1.4.1-2-gfad0