summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-09-05 01:02:46 +0300
committerZahary Karadjov <zahary@gmail.com>2014-09-05 01:02:46 +0300
commit7d5e387a488200113664a3ffa60e5c63ec32c54b (patch)
treeeba35e8e26f394d4393ab9392d2d973d4cf8cf30
parent9a3963f51b6e5ed25befa766270b1bbf5155e090 (diff)
downloadNim-7d5e387a488200113664a3ffa60e5c63ec32c54b.tar.gz
mostly fixes #1339
The compiler hangs were caused by the interaction of tyError and the instantiation caches.
For procs, the cache wasn't able to find previously compiled proc featuring tyError in the signature.
For types, the unresolved type parameters leading to tyError were not replaced everywhere leading
to endless replaceTypeVarsT recursion for cyclic types.

The fix is still not perfect, because the handling of tyError in other places in the compiler doesn't seem
to be complete and the first test case now results in internal error (still, much better than a hang blocking
your IDE).
-rw-r--r--compiler/semtypinst.nim8
-rw-r--r--compiler/types.nim4
2 files changed, 9 insertions, 3 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 9484bbe90..4563dc8d4 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -216,12 +216,16 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
     result.typ = replaceTypeVarsT(cl, s.typ)
     result.ast = replaceTypeVarsN(cl, s.ast)
     
-proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = 
+proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
   result = PType(idTableGet(cl.typeMap, t))
   if result == nil:
     if cl.allowMetaTypes or tfRetType in t.flags: return
     localError(t.sym.info, errCannotInstantiateX, typeToString(t))
     result = errorType(cl.c)
+    # In order to prevent endless recursions, we must remember
+    # this bad lookup and replace it with errorType everywhere.
+    # These code paths are only active in nimrod check
+    idTablePut(cl.typeMap, t, result)
   elif result.kind == tyGenericParam and not cl.allowMetaTypes:
     internalError(cl.info, "substitution with generic parameter")
 
@@ -353,7 +357,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
 
   of tyGenericBody:
     localError(cl.info, errCannotInstantiateX, typeToString(t))
-    result = t
+    result = errorType(cl.c)
     #result = replaceTypeVarsT(cl, lastSon(t))
 
   of tyFromExpr:
diff --git a/compiler/types.nim b/compiler/types.nim
index adc03a13e..7b59fbf20 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -913,9 +913,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
           result = sameTypeAux(a.sons[0], b.sons[0], c)     
     else: 
       result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b)
-  of tyEnum, tyForward, tyProxy:
+  of tyEnum, tyForward:
     # XXX generic enums do not make much sense, but require structural checking
     result = a.id == b.id and sameFlags(a, b)
+  of tyError:
+    result = b.kind == tyError
   of tyTuple:
     cycleCheck()
     result = sameTuple(a, b, c) and sameFlags(a, b)