summary refs log tree commit diff stats
path: root/compiler/seminst.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/seminst.nim')
-rwxr-xr-xcompiler/seminst.nim44
1 files changed, 38 insertions, 6 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 1da6a671f..9ec78488b 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -8,6 +8,7 @@
 #
 
 # This module implements the instantiation of generic procs.
+# included from sem.nim
 
 proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
                                  entry: var TInstantiatedSymbol) = 
@@ -106,6 +107,35 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
       s.ast.sons[genericParamsPos].kind == nkEmpty:
     c.threadEntries.add(s)
 
+template nimdbg: expr = c.filename.endsWith"nimdbg.nim"
+
+proc applyConcreteTypesToSig(genericProc: PSym, concTypes: seq[PType]): PType =
+  # XXX: This is intended to replace the use of semParamList in generateInstance.
+  # The results of semParamList's analysis are already encoded in the original
+  # proc type and any concrete types may be aplied directly over it.
+  # Besides being more efficient, it will remove the awkward case of
+  # genericParams == nil in semParamList.
+  # Currenly, it fails in some cases such as:
+  # proc inc2*[T](x: var ordinal[T], y = 1) {.magic: "Inc", noSideEffect.}
+  let sig = genericProc.typ
+  result = copyType(sig, getCurrOwner(), false)
+  result.n = sig.n.shallowCopy
+  
+  for i in countup(0, sig.len - 1):
+    let tOrig = sig.sons[i]
+    if tOrig == nil: continue        
+    let oGenParams = genericProc.ast.sons[genericParamsPos]
+    if skipTypes(tOrig, skipPtrs).kind in {tyGenericParam}:
+      var tConcrete = concTypes[tOrig.sym.position]
+      if i > 0:
+        let param = sig.n.sons[i].sym.copySym
+        param.typ = tConcrete
+        result.n.sons[i] = newSymNode(param)
+      result.sons[i] = tConcrete
+    else:
+      result.sons[i] = tOrig
+      if i > 0: result.n.sons[i] = sig.n.sons[i]
+
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, 
                       info: TLineInfo): PSym = 
   # generates an instantiated proc
@@ -133,12 +163,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry)
   n.sons[genericParamsPos] = ast.emptyNode
   # semantic checking for the parameters:
-  if n.sons[paramsPos].kind != nkEmpty: 
-    removeDefaultParamValues(n.sons[ParamsPos])
-    semParamList(c, n.sons[ParamsPos], nil, result)
-    # XXX: obsoleted - happens in semParamList # 
-    # addParams(c, result.typ.n)
-  else: 
+  if n.sons[paramsPos].kind != nkEmpty:
+    if false and nimdbg:
+      result.typ = applyConcreteTypesToSig(fn, entry.concreteTypes)
+      addParams(c, result.typ.n, fn.kind)
+    else:
+      removeDefaultParamValues(n.sons[ParamsPos])
+      semParamList(c, n.sons[ParamsPos], nil, result)
+  else:
     result.typ = newTypeS(tyProc, c)
     addSon(result.typ, nil)
   result.typ.callConv = fn.typ.callConv