summary refs log tree commit diff stats
path: root/compiler/seminst.nim
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-05-26 17:04:01 +0300
committerZahary Karadjov <zahary@gmail.com>2013-05-26 18:06:01 +0300
commit4ae4005f805c5b2e329b2e060fcf40169238a9f9 (patch)
treec14155e848197e56d7db09cfd3b5285e222c772b /compiler/seminst.nim
parentd5fffc032f2b390abd7b4c4fea2e49b1a0ef9736 (diff)
downloadNim-4ae4005f805c5b2e329b2e060fcf40169238a9f9.tar.gz
further fixes for void stripping. fixes tvoid.
Diffstat (limited to 'compiler/seminst.nim')
-rw-r--r--compiler/seminst.nim45
1 files changed, 25 insertions, 20 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 98f25efa7..ed842d98e 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -148,8 +148,8 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType): PType =
 proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
   result = instGenericContainer(c, n.info, header)
 
-proc fixupProcTypeR(c: PContext, genericType: PType,
-                    inst: TInstantiation): PType =
+proc fixupProcType(c: PContext, genericType: PType,
+                   inst: TInstantiation): PType =
   result = genericType
   if result == nil: return
 
@@ -167,48 +167,53 @@ proc fixupProcTypeR(c: PContext, genericType: PType,
     if genericType.sons == nil: return
     var head = 0
     for i in 0 .. <genericType.sons.len:
-      let changed = fixupProcTypeR(c, genericType.sons[i], inst)
+      var changed = fixupProcType(c, genericType.sons[i], inst)
       if changed != genericType.sons[i]:
+        var changed = changed.skipIntLit
         if result == genericType:
           # the first detected change initializes the result
           result = copyType(genericType, genericType.owner, false)
           if genericType.n != nil:
             result.n = copyTree(genericType.n)
-        if changed.kind == tyEmpty:
-          result.sons[i..i] = []
-          if result.n != nil: result.n.sons[i..i] = []
-          continue
-        let changed = changed.skipIntLit
+
+        # XXX: doh, we have to treat seq and arrays as special case
+        # because sometimes the `@` magic will be applied to an empty
+        # sequence having the type tySequence(tyEmpty)
+        if changed.kind == tyEmpty and
+           genericType.kind notin {tyArray, tySequence}:
+          if genericType.kind == tyProc and i == 0:
+            # return types of procs are overwritten with nil
+            changed = nil
+          else:
+            # otherwise, `empty` is just erased from the signature
+            result.sons[i..i] = []
+            if result.n != nil: result.n.sons[i..i] = []
+            continue
+        
         result.sons[head] = changed
+        
         if result.n != nil:
           if result.n.kind == nkRecList:
             result.n.sons[head].typ = changed
           if result.n.kind == nkFormalParams:
-            if i == 0:
-              nil
-            else:
+            if i != 0:
               let origParam = result.n.sons[head].sym
               var param = copySym(origParam)
               param.typ = changed
               param.ast = origParam.ast
               result.n.sons[head] = newSymNode(param)
+
+      # won't be advanced on empty (void) nodes
       inc head
         
   of tyGenericInvokation:
     result = newTypeWithSons(c, tyGenericInvokation, genericType.sons)
     for i in 1 .. <genericType.sons.len:
-      result.sons[i] = fixupProcTypeR(c, result.sons[i], inst)
+      result.sons[i] = fixupProcType(c, result.sons[i], inst)
     result = instGenericContainer(c, getInfoContext(-1), result)
   else:
     nil
 
-proc fixupProcType(c: PContext, genericType: PType,
-                   inst: TInstantiation): PType =
-  result = copyType(genericType, genericType.owner, false)
-  result = fixupProcTypeR(c, result, inst)
-  for i in 0 .. <result.sons.len:
-    result.sons[i] = fixupProcTypeR(c, result.sons[i], inst)
-
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
                       info: TLineInfo): PSym =
   # no need to instantiate generic templates/macros:
@@ -238,7 +243,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   var entry = TInstantiation.new
   entry.sym = result
   instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
-  result.typ = fixupProcTypeR(c, fn.typ, entry[])
+  result.typ = fixupProcType(c, fn.typ, entry[])
   n.sons[genericParamsPos] = ast.emptyNode
   var oldPrc = GenericCacheGet(fn, entry[])
   if oldPrc == nil: