summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-12-28 12:50:45 +0200
committerZahary Karadjov <zahary@gmail.com>2013-12-28 12:50:45 +0200
commita59f13b00dff570865201e860ea24d202b60c85a (patch)
tree931818f7a12e6ca31c8f62d46f39cc64e1804395 /compiler
parenta27eb51535f9ff233b67e5bac80cc51b81c343c7 (diff)
downloadNim-a59f13b00dff570865201e860ea24d202b60c85a.tar.gz
lift generic parameters from concrete composite type classes
Diffstat (limited to 'compiler')
-rw-r--r--compiler/seminst.nim5
-rw-r--r--compiler/semtypes.nim17
-rw-r--r--compiler/semtypinst.nim9
-rw-r--r--compiler/types.nim17
4 files changed, 29 insertions, 19 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 250e53ed6..ba26635a1 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -204,6 +204,8 @@ proc fixupProcType(c: PContext, genericType: PType,
       result = result.sons[0]
   of tyStatic:
     result = inst.concreteTypes[genericType.sym.position]
+  of tyGenericInst:
+    result = fixupProcType(c, result.lastSon, inst)
   of tyOpenArray, tyArray, tySet, tySequence, tyTuple, tyProc,
      tyPtr, tyVar, tyRef, tyOrdinal, tyRange, tyVarargs:
     if genericType.sons == nil: return
@@ -234,7 +236,8 @@ proc fixupProcType(c: PContext, genericType: PType,
             continue
         
         result.sons[head] = changed
-        
+        result.size = 0
+
         if result.n != nil:
           if result.n.kind == nkRecList:
             for son in result.n.sons:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index d3a934c21..6f6d0c4c5 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -620,7 +620,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
     s.position = genericParams.len
     genericParams.addSon(newSymNode(s))
     result = typeClass
-
+ 
   # XXX: There are codegen errors if this is turned into a nested proc
   template liftingWalk(typ: PType, anonFlag = false): expr =
     liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag)
@@ -665,6 +665,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
         if lifted != nil:
           paramType.sons[i] = lifted
           result = paramType
+  
   of tyGenericBody:
     result = newTypeS(tyGenericInvokation, c)
     result.rawAddSon(paramType)
@@ -674,6 +675,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
                                   allowMetaTypes = true)
     result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
     result = addImplicitGeneric(result)
+  
   of tyGenericInst:
     for i in 1 .. (paramType.sons.len - 2):
       var lifted = liftingWalk(paramType.sons[i])
@@ -681,21 +683,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
         paramType.sons[i] = lifted
         result = paramType
 
-    if result == nil:
-      result = liftingWalk(paramType.lastSon)
-    else:
-      result.kind = tyGenericInvokation
-      result.sons.setLen(result.sons.len - 1)
+    let liftBody = liftingWalk(paramType.lastSon)
+    if liftBody != nil: result = liftBody
+
   of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
-    result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false))
+    result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
+  
   of tyExpr:
     result = addImplicitGeneric(newTypeS(tyGenericParam, c))
+  
   of tyGenericParam:
     if tfGenericTypeParam in paramType.flags and false:
       if paramType.sonsLen > 0:
         result = liftingWalk(paramType.lastSon)
       else:
         result = addImplicitGeneric(newTypeS(tyGenericParam, c))
+  
   else: nil
 
   # result = liftingWalk(paramType)
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index f7750171d..384ce3498 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -17,14 +17,14 @@ proc checkPartialConstructedType(info: TLineInfo, t: PType) =
   elif t.kind == tyVar and t.sons[0].kind == tyVar:
     LocalError(info, errVarVarTypeNotAllowed)
 
-proc checkConstructedType*(info: TLineInfo, typ: PType) = 
+proc checkConstructedType*(info: TLineInfo, typ: PType) =
   var t = typ.skipTypes({tyDistinct})
   if t.kind in tyTypeClasses: nil
   elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: 
     LocalError(info, errInvalidPragmaX, "acyclic")
   elif t.kind == tyVar and t.sons[0].kind == tyVar: 
     LocalError(info, errVarVarTypeNotAllowed)
-  elif computeSize(t) < 0:
+  elif computeSize(t) == szIllegalRecursion:
     LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
   when false:
     if t.kind == tyObject and t.sons[0] != nil:
@@ -140,7 +140,7 @@ proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType =
     result = errorType(cl.c)
   elif result.kind == tyGenericParam and not cl.allowMetaTypes:
     InternalError(cl.info, "substitution with generic parameter")
-  
+ 
 proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = 
   # tyGenericInvokation[A, tyGenericInvokation[A, B]]
   # is difficult to handle: 
@@ -170,7 +170,8 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
   # recursive instantions:
   result = newType(tyGenericInst, t.sons[0].owner)
   result.rawAddSon(header.sons[0])
-  cacheTypeInst(result)
+  if not cl.allowMetaTypes:
+    cacheTypeInst(result)
 
   for i in countup(1, sonsLen(t) - 1):
     var x = replaceTypeVarsT(cl, t.sons[i])
diff --git a/compiler/types.nim b/compiler/types.nim
index 1b25a396c..d47015836 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1098,18 +1098,22 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt =
     a = 1
     result = - 1
 
-proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = 
+const 
+  szIllegalRecursion* = -2
+  szUnknownSize* = -1
+
+proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
   var res, maxAlign, length, currOffset: biggestInt
-  if typ.size == - 2: 
+  if typ.size == szIllegalRecursion:
     # we are already computing the size of the type
     # --> illegal recursion in type
-    return - 2
-  if typ.size >= 0: 
+    return szIllegalRecursion
+  if typ.size >= 0:
     # size already computed
     result = typ.size
     a = typ.align
     return 
-  typ.size = - 2              # mark as being computed
+  typ.size = szIllegalRecursion # mark as being computed
   case typ.kind
   of tyInt, tyUInt: 
     result = IntSize
@@ -1196,7 +1200,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
   of tyProxy: result = 1
   else:
     #internalError("computeSizeAux()")
-    result = - 1
+    result = szUnknownSize
   typ.size = result
   typ.align = int(a)
 
@@ -1213,7 +1217,6 @@ proc getSize(typ: PType): biggestInt =
   result = computeSize(typ)
   if result < 0: InternalError("getSize: " & $typ.kind)
 
-  
 proc containsGenericTypeIter(t: PType, closure: PObject): bool = 
   result = t.kind in GenericTypes