summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-02-26 00:11:21 +0100
committerAraq <rumpf_a@web.de>2015-02-26 02:05:23 +0100
commit9053799bf57df4043923b5635806185cf997428e (patch)
tree7208584a8b4099cbf22a92245e3210dca130922b /compiler
parent5d9663e4de8b2f2502d7bd76243b39a12415cd05 (diff)
downloadNim-9053799bf57df4043923b5635806185cf997428e.tar.gz
fixes #2216
Diffstat (limited to 'compiler')
-rw-r--r--compiler/sem.nim9
-rw-r--r--compiler/semtypes.nim3
-rw-r--r--compiler/semtypinst.nim8
-rw-r--r--compiler/sigmatch.nim16
4 files changed, 20 insertions, 16 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 2d69d4213..a90948245 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -95,15 +95,6 @@ proc inferWithMetatype(c: PContext, formal: PType,
 
 var commonTypeBegin = PType(kind: tyExpr)
 
-proc isEmptyContainer(t: PType): bool =
-  case t.kind
-  of tyExpr, tyNil: result = true
-  of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty
-  of tySet, tySequence, tyOpenArray, tyVarargs:
-    result = t.sons[0].kind == tyEmpty
-  of tyGenericInst: result = isEmptyContainer(t.lastSon)
-  else: result = false
-
 proc commonType*(x, y: PType): PType =
   # new type relation that is used for array constructors,
   # if expressions, etc.:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 4e3823f42..9f2f755a0 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1145,7 +1145,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
         case n.len
         of 3:
           result = semTypeNode(c, n.sons[1], prev)
-          if result.kind in NilableTypes and n.sons[2].kind == nkNilLit:
+          if result.skipTypes({tyGenericInst}).kind in NilableTypes+GenericTypes and
+              n.sons[2].kind == nkNilLit:
             result = freshType(result, prev)
             result.flags.incl(tfNotNil)
           else:
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 452942ec0..86826567e 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -236,7 +236,7 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
 
 proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = 
   # tyGenericInvocation[A, tyGenericInvocation[A, B]]
-  # is difficult to handle: 
+  # is difficult to handle:
   var body = t.sons[0]
   if body.kind != tyGenericBody: internalError(cl.info, "no generic body")
   var header: PType = t
@@ -245,7 +245,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
     result = PType(idTableGet(cl.localCache, t))
   else:
     result = searchInstTypes(t)
-  if result != nil: return
+  if result != nil and eqTypeFlags*result.flags == eqTypeFlags*t.flags: return
   for i in countup(1, sonsLen(t) - 1):
     var x = t.sons[i]
     if x.kind == tyGenericParam:
@@ -260,10 +260,10 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
   if header != t:
     # search again after first pass:
     result = searchInstTypes(header)
-    if result != nil: return
+    if result != nil and eqTypeFlags*result.flags == eqTypeFlags*t.flags: return
   else:
     header = instCopyType(cl, t)
-  
+
   result = newType(tyGenericInst, t.sons[0].owner)
   result.flags = header.flags
   # be careful not to propagate unnecessary flags here (don't use rawAddSon)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 30d51aa29..8cea86db5 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1165,6 +1165,15 @@ proc isInlineIterator*(t: PType): bool =
   result = t.kind == tyIter or
           (t.kind == tyBuiltInTypeClass and t.base.kind == tyIter)
 
+proc isEmptyContainer*(t: PType): bool =
+  case t.kind
+  of tyExpr, tyNil: result = true
+  of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty
+  of tySet, tySequence, tyOpenArray, tyVarargs:
+    result = t.sons[0].kind == tyEmpty
+  of tyGenericInst: result = isEmptyContainer(t.lastSon)
+  else: result = false
+
 proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
                         argSemantized, argOrig: PNode): PNode =
   var
@@ -1260,11 +1269,14 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
       result = implicitConv(nkHiddenStdConv, f, result, m, c)
   of isGeneric:
     inc(m.genericMatches)
-    when false:
+    when true:
       if skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple:
         result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
-      else:
+      elif arg.typ != nil and arg.typ.isEmptyContainer:
         result = arg.copyTree
+        result.typ = getInstantiatedType(c, arg, m, f)
+      else:
+        result = arg
     else:
       # XXX Why is this ever necessary? arg's type should not be retrofitted
       # to match formal's type in this way!