summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ast.nim5
-rwxr-xr-xcompiler/semtypinst.nim4
-rwxr-xr-xcompiler/sigmatch.nim17
-rwxr-xr-xcompiler/transf.nim2
-rwxr-xr-xcompiler/types.nim6
5 files changed, 25 insertions, 9 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 340a14888..83bd360f2 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -287,6 +287,11 @@ type
     tyGenericInvokation, # ``T[a, b]`` for types to invoke
     tyGenericBody,       # ``T[a, b, body]`` last parameter is the body
     tyGenericInst,       # ``T[a, b, realInstance]`` instantiated generic type
+                         # realInstance will be a concrete type like tyObject
+                         # unless this is an instance of a generic alias type.
+                         # then realInstance will be the tyGenericInst of the
+                         # completely (recursively) resolved alias.
+                         
     tyGenericParam,      # ``a`` in the above patterns
     tyDistinct,
     tyEnum,
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index d51e24c89..e12640945 100755
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -171,6 +171,10 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
     result.flags = result.flags + newbody.flags
     newbody.callConv = body.callConv
     newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
+    # This type may be a generic alias and we want to resolve it here.
+    # One step is enough, because the recursive nature of
+    # handleGenericInvokation will handle the alias-to-alias-to-alias case
+    if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
     rawAddSon(result, newbody)
     checkPartialConstructedType(cl.info, newbody)
   else:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 8968e4e03..f1920a255 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -476,22 +476,23 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
     let ff = lastSon(f)
     if ff != nil: result = typeRel(c, ff, a)
   of tyGenericInvokation:
+    var x = a.skipGenericAlias
     assert(f.sons[0].kind == tyGenericBody)
-    if a.kind == tyGenericInvokation: 
+    if x.kind == tyGenericInvokation:
       #InternalError("typeRel: tyGenericInvokation -> tyGenericInvokation")
       # simply no match for now:
       nil
-    elif a.kind == tyGenericInst and 
-          (f.sons[0].containerID == a.sons[0].containerID) and
-          (sonsLen(a) - 1 == sonsLen(f)): 
-      assert(a.sons[0].kind == tyGenericBody)
+    elif x.kind == tyGenericInst and 
+          (f.sons[0].containerID == x.sons[0].containerID) and
+          (sonsLen(x) - 1 == sonsLen(f)): 
+      assert(x.sons[0].kind == tyGenericBody)
       for i in countup(1, sonsLen(f) - 1): 
-        if a.sons[i].kind == tyGenericParam: 
+        if x.sons[i].kind == tyGenericParam: 
           InternalError("wrong instantiated type!")
-        elif typeRel(c, f.sons[i], a.sons[i]) <= isSubtype: return 
+        elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype: return 
       result = isGeneric
     else:
-      result = typeRel(c, f.sons[0], a)
+      result = typeRel(c, f.sons[0], x)
       if result != isNone:
         # we steal the generic parameters from the tyGenericBody:
         for i in countup(1, sonsLen(f) - 1):
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 170f8ff0f..d1ee76cf1 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -603,7 +603,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
     dec c.inLoop
   of nkCaseStmt: result = transformCase(c, n)
   of nkContinueStmt:
-    result = PTransNode(newNode(nkBreakStmt))
+    result = PTransNode(newNodeI(nkBreakStmt, n.info))
     var labl = c.contSyms[c.contSyms.high]
     add(result, PTransNode(newSymNode(labl)))
   of nkBreakStmt: result = transformBreak(c, n)
diff --git a/compiler/types.nim b/compiler/types.nim
index e02d93233..90fffff40 100755
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -905,6 +905,12 @@ 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 matchTypeClass*(bindings: var TIdTable, typeClass, t: PType): bool =
   for i in countup(0, typeClass.sonsLen - 1):
     let req = typeClass.sons[i]