summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim3
-rw-r--r--compiler/lambdalifting.nim2
-rw-r--r--compiler/seminst.nim37
-rw-r--r--compiler/semtypes.nim2
4 files changed, 25 insertions, 19 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 5f6b658cf..25c66e117 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1359,7 +1359,8 @@ proc getStrOrChar*(a: PNode): string =
 proc isGenericRoutine*(s: PSym): bool = 
   case s.kind
   of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter:
-    result = sfFromGeneric in s.flags
+    result = sfFromGeneric in s.flags or
+             (s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty)
   else: nil
 
 proc isRoutine*(s: PSym): bool {.inline.} =
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 163ea4136..9a40b350e 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -220,7 +220,7 @@ proc getHiddenParam(routine: PSym): PSym =
 
 proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
   result = s.kind in {skProc, skMethod, skConverter} and
-    s.owner == outerProc and not isGenericRoutine(s)
+    s.owner == outerProc
   #s.typ.callConv == ccClosure
 
 proc addClosureParam(i: PInnerContext, e: PEnv) =
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index ed842d98e..15be33261 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -91,17 +91,8 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
     addDecl(c, result)
     pushProcCon(c, result)
     # add params to scope
-    let origFormalParams = result.typ.n
-    result.typ.n = newNodeI(nkFormalParams,
-                            origFormalParams.info,
-                            origFormalParams.len)
-    result.typ.n.sons[0] = copyNode(origFormalParams.sons[0])
-    for i in 1 .. <result.typ.len:
-      let origParam = origFormalParams[i].sym
-      var param = copySym(origParam)
-      result.typ.n.sons[i] = newSymNode(param)
-      param.typ = result.typ.sons[i]
-      param.ast = origParam.ast
+    for i in 1 .. <result.typ.n.len:
+      var param = result.typ.n.sons[i].sym
       param.owner = result
       addParamOrResult(c, param, result.kind)
     # debug result.typ.n
@@ -150,6 +141,15 @@ proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
 
 proc fixupProcType(c: PContext, genericType: PType,
                    inst: TInstantiation): PType =
+  # XXX: This is starting to look suspiciously like ReplaceTypeVarsT
+  # there are few apparent differences, but maybe the code could be
+  # moved over.
+  # * the code here uses the new genericSym.position property when
+  #   doing lookups. 
+  # * the handling of tyTypeDesc seems suspicious in ReplaceTypeVarsT
+  #   typedesc params were previously handled in the second pass of
+  #   semParamList
+  # * void (nkEmpty) params doesn't seem to be stripped in ReplaceTypeVarsT
   result = genericType
   if result == nil: return
 
@@ -167,7 +167,8 @@ proc fixupProcType(c: PContext, genericType: PType,
     if genericType.sons == nil: return
     var head = 0
     for i in 0 .. <genericType.sons.len:
-      var changed = fixupProcType(c, genericType.sons[i], inst)
+      let origType = genericType.sons[i]
+      var changed = fixupProcType(c, origType, inst)
       if changed != genericType.sons[i]:
         var changed = changed.skipIntLit
         if result == genericType:
@@ -194,7 +195,11 @@ proc fixupProcType(c: PContext, genericType: PType,
         
         if result.n != nil:
           if result.n.kind == nkRecList:
-            result.n.sons[head].typ = changed
+            for son in result.n.sons:
+              if son.typ == origType:
+                son.typ = changed
+                son.sym = copySym(son.sym, true)
+                son.sym.typ = changed
           if result.n.kind == nkFormalParams:
             if i != 0:
               let origParam = result.n.sons[head].sym
@@ -205,14 +210,14 @@ proc fixupProcType(c: PContext, genericType: PType,
 
       # 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] = fixupProcType(c, result.sons[i], inst)
     result = instGenericContainer(c, getInfoContext(-1), result)
-  else:
-    nil
+  
+  else: nil
 
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
                       info: TLineInfo): PSym =
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index bb6c646f2..2c6fc4738 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -384,7 +384,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
       # for ``{}`` we want to trigger the type mismatch in ``fitNode``:
       if r.kind != nkCurly or len(r) == 0:
         checkMinSonsLen(t, 1)
-        branch.sons[i] = fitNode(c, t.sons[0].typ, r)
+        branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r))
         inc(covered)
       else:
         # constant sets have special rules