summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgtypes.nim1
-rw-r--r--compiler/sighashes.nim29
-rw-r--r--tests/ccgbugs/tsighash_typename_regression.nim15
3 files changed, 32 insertions, 13 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 23e16cb93..c557123ac 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -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
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index 218011b1d..3096d94a0 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -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:
diff --git a/tests/ccgbugs/tsighash_typename_regression.nim b/tests/ccgbugs/tsighash_typename_regression.nim
index 6e49bafc3..b93eebd20 100644
--- a/tests/ccgbugs/tsighash_typename_regression.nim
+++ b/tests/ccgbugs/tsighash_typename_regression.nim
@@ -15,3 +15,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)