summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/types.nim28
1 files changed, 20 insertions, 8 deletions
diff --git a/compiler/types.nim b/compiler/types.nim
index d7410c67a..ae31d24de 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -830,6 +830,12 @@ proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
     result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
     if not result: return 
 
+proc isGenericAlias*(t: PType): bool =
+  return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst
+
+proc skipGenericAlias*(t: PType): PType =
+  return if t.isGenericAlias: t.lastSon else: t
+
 proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
   template cycleCheck() =
     # believe it or not, the direct check for ``containsOrIncl(c, a, b)``
@@ -860,6 +866,19 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
     of dcEqOrDistinctOf:
       while a.kind == tyDistinct: a = a.sons[0]
       if a.kind != b.kind: return false
+  
+  if x.kind == tyGenericInst:
+    let
+      lhs = x.skipGenericAlias
+      rhs = y.skipGenericAlias
+    if rhs.kind != tyGenericInst or lhs.base != rhs.base:
+      return false
+    for i in 1 .. lhs.len - 2:
+      let ff = rhs.sons[i]
+      let aa = lhs.sons[i]
+      if not sameTypeAux(ff, aa, c): return false
+    return true
+
   case a.kind
   of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
      tyInt..tyBigNum, tyStmt, tyExpr:
@@ -884,8 +903,6 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
   of tyTuple:
     cycleCheck()
     result = sameTuple(a, b, c) and sameFlags(a, b)
-  of tyGenericInst:    
-    result = sameTypeAux(lastSon(a), lastSon(b), c)
   of tyTypeDesc:
     if c.cmp == dcEqIgnoreDistinct: result = false
     elif ExactTypeDescValues in c.flags:
@@ -912,6 +929,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
     result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
         sameValue(a.n.sons[0], b.n.sons[0]) and
         sameValue(a.n.sons[1], b.n.sons[1])
+  of tyGenericInst: discard
   of tyNone: result = false  
 
 proc sameBackendType*(x, y: PType): bool =
@@ -1005,12 +1023,6 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
     a = a.sons[i]
   result = a.kind == last
 
-proc isGenericAlias*(t: PType): bool =
-  return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst
-
-proc skipGenericAlias*(t: PType): PType =
-  return if t.isGenericAlias: t.lastSon else: t
-
 proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
                     flags: TTypeAllowedFlags = {}): bool =
   assert(kind in {skVar, skLet, skConst, skParam, skResult})