summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-12-29 16:08:33 +0200
committerZahary Karadjov <zahary@gmail.com>2013-12-29 16:08:33 +0200
commit72291875bf895e8e0d22ab3f375752417b07ed25 (patch)
tree98bfd4c616465b9d98a927e742120e9303695e77 /compiler
parent66a255652572b48440b68878e99d7f5290e384b3 (diff)
downloadNim-72291875bf895e8e0d22ab3f375752417b07ed25.tar.gz
integrate the logic of fixupProcType into ReplaceTypeVars
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim20
-rw-r--r--compiler/semdata.nim14
-rw-r--r--compiler/seminst.nim3
-rw-r--r--compiler/semtypes.nim19
-rw-r--r--compiler/semtypinst.nim42
-rw-r--r--compiler/sigmatch.nim15
-rw-r--r--compiler/types.nim5
7 files changed, 76 insertions, 42 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 45784bbcb..92f3ce8d3 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -351,9 +351,12 @@ const
   tyPureObject* = tyTuple
   GcTypeKinds* = {tyRef, tySequence, tyString}
   tyError* = tyProxy # as an errornous node should match everything
+  
   tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass,
                     tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything}
 
+  tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyStatic, tyExpr} + tyTypeClasses
+ 
 type
   TTypeKinds* = set[TTypeKind]
 
@@ -397,7 +400,8 @@ type
     tfNeedsInit,      # type constains a "not nil" constraint somewhere or some
                       # other type so that it requires inititalization
     tfHasShared,      # type constains a "shared" constraint modifier somewhere
-    tfHasMeta,        # type has "typedesc" or "expr" somewhere; or uses '|'
+    tfHasMeta,        # type contains "wildcard" sub-types such as generic params
+                      # or other type classes
     tfHasGCedMem,     # type contains GC'ed memory
     tfGenericTypeParam
     tfHasStatic
@@ -777,9 +781,11 @@ const
 
   GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody, 
     tyGenericParam}
+  
   StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, 
     tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray,
     tyVarargs}
+  
   ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
                                  # var x = expr
     tyBool, tyChar, tyEnum, tyArray, tyObject, 
@@ -1222,7 +1228,7 @@ proc newSons(father: PNode, length: int) =
 proc propagateToOwner*(owner, elem: PType) =
   const HaveTheirOwnEmpty = {tySequence, tySet}
   owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta,
-                                             tfHasGCedMem})
+                                             tfHasStatic, tfHasGCedMem})
   if tfNotNil in elem.flags:
     if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
       owner.flags.incl tfNotNil
@@ -1235,10 +1241,14 @@ proc propagateToOwner*(owner, elem: PType) =
     
   if tfShared in elem.flags:
     owner.flags.incl tfHasShared
-  
-  if elem.kind in {tyExpr, tyStatic, tyTypeDesc}:
+ 
+  if elem.kind in tyMetaTypes:
     owner.flags.incl tfHasMeta
-  elif elem.kind in {tyString, tyRef, tySequence} or
+
+  if elem.kind == tyStatic:
+    owner.flags.incl tfHasStatic
+
+  if elem.kind in {tyString, tyRef, tySequence} or
       elem.kind == tyProc and elem.callConv == ccClosure:
     owner.flags.incl tfHasGCedMem
 
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 874e5dab4..687140ce9 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -217,23 +217,21 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
 proc makeAndType*(c: PContext, t1, t2: PType): PType =
   result = newTypeS(tyAnd, c)
   result.sons = @[t1, t2]
-  result.flags.incl tfHasMeta
-  if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
-    result.flags.incl tfHasStatic
+  propagateToOwner(result, t1)
+  propagateToOwner(result, t2)
 
 proc makeOrType*(c: PContext, t1, t2: PType): PType =
   result = newTypeS(tyOr, c)
   result.sons = @[t1, t2]
-  result.flags.incl tfHasMeta
-  if tfHasStatic in t1.flags or tfHasStatic in t2.flags:
-    result.flags.incl tfHasStatic
+  propagateToOwner(result, t1)
+  propagateToOwner(result, t2)
 
 proc makeNotType*(c: PContext, t1: PType): PType =
   result = newTypeS(tyNot, c)
   result.sons = @[t1]
-  result.flags.incl tfHasMeta
+  propagateToOwner(result, t1)
 
-proc newTypeS(kind: TTypeKind, c: PContext): PType = 
+proc newTypeS(kind: TTypeKind, c: PContext): PType =
   result = newType(kind, getCurrOwner())
 
 proc newTypeWithSons*(c: PContext, kind: TTypeKind,
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 969ff2d59..cfa099d3f 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -310,7 +310,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   var entry = TInstantiation.new
   entry.sym = result
   instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
-  result.typ = fixupProcType(c, fn.typ, entry[])
+  # let t1 = fixupProcType(c, fn.typ, entry[])
+  result.typ = generateTypeInstance(c, pt, info, fn.typ)
   n.sons[genericParamsPos] = ast.emptyNode
   var oldPrc = GenericCacheGet(fn, entry[])
   if oldPrc == nil:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 29fad0059..0562509db 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -591,6 +591,10 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
 
 let typedescId = getIdent"typedesc"
 
+template shouldHaveMeta(t) =
+  InternalAssert tfHasMeta in result.lastSon.flags
+  # result.lastSon.flags.incl tfHasMeta
+
 proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
                    paramType: PType, paramName: string,
                    info: TLineInfo, anon = false): PType =
@@ -615,7 +619,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)
@@ -674,24 +678,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
       result.rawAddSon(copyType(paramType.sons[i], getCurrOwner(), true))
     result = instGenericContainer(c, paramType.sym.info, result,
                                   allowMetaTypes = true)
-    result.lastSon.flags.incl tfHasMeta
+    result.lastSon.shouldHaveMeta
     result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
     result = addImplicitGeneric(result)
   
   of tyGenericInst:
-    # XXX: It should be possible to set tfHasMeta in semtypinst, when the
-    # instance was generated
     for i in 1 .. (paramType.sons.len - 2):
       var lifted = liftingWalk(paramType.sons[i])
       if lifted != nil:
         paramType.sons[i] = lifted
         result = paramType
-        paramType.lastSon.flags.incl tfHasMeta
+        result.lastSon.shouldHaveMeta
 
     let liftBody = liftingWalk(paramType.lastSon)
     if liftBody != nil:
       result = liftBody
-      result.flags.incl tfHasMeta
+      result.shouldHaveMeta
     
   of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
     result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
@@ -884,7 +886,10 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
         when oUseLateInstantiation:
           result = lateInstantiateGeneric(c, result, n.info)
         else:
-          result = instGenericContainer(c, n, result)
+          result = instGenericContainer(c, n.info, result,
+                                        allowMetaTypes = not isConcrete)
+          if not isConcrete and result.kind == tyGenericInst:
+            result.lastSon.shouldHaveMeta
 
 proc semTypeExpr(c: PContext, n: PNode): PType =
   var n = semExprWithType(c, n, {efDetermineType})
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 1bd6e23d5..1a4bdd9e3 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -135,7 +135,7 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
 proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = 
   result = PType(idTableGet(cl.typeMap, t))
   if result == nil:
-    if cl.allowMetaTypes: return
+    if cl.allowMetaTypes or tfRetType in t.flags: return
     LocalError(t.sym.info, errCannotInstantiateX, typeToString(t))
     result = errorType(cl.c)
   elif result.kind == tyGenericParam and not cl.allowMetaTypes:
@@ -184,7 +184,7 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
     # if one of the params is not concrete, we cannot do anything
     # but we already raised an error!
     rawAddSon(result, header.sons[i])
-  
+ 
   var newbody = ReplaceTypeVarsT(cl, lastSon(body))
   newbody.flags = newbody.flags + t.flags + body.flags
   result.flags = result.flags + newbody.flags
@@ -205,20 +205,29 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
     return if s != nil: s else: t
 
   case t.kind
-  of tyTypeClass, tyBuiltInTypeClass: nil
-  of tyGenericParam, tyCompositeTypeClass:
-    result = lookupTypeVar(cl, t)
-    if result == nil: return t
-    if result.kind == tyGenericInvokation:
-      result = handleGenericInvokation(cl, result)
-  of tyGenericInvokation: 
+  of tyGenericParam, tyTypeClasses:
+    let lookup = lookupTypeVar(cl, t)
+    if lookup != nil:
+      result = lookup
+      if result.kind == tyGenericInvokation:
+        result = handleGenericInvokation(cl, result)
+  of tyGenericInvokation:
     result = handleGenericInvokation(cl, t)
   of tyGenericBody:
-    InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
+    InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody" )
     result = ReplaceTypeVarsT(cl, lastSon(t))
   of tyInt:
     result = skipIntLit(t)
     # XXX now there are also float literals
+  of tyTypeDesc:
+    let lookup = PType(idTableGet(cl.typeMap, t)) # lookupTypeVar(cl, t)
+    if lookup != nil:
+      result = lookup
+      if tfUnresolved in t.flags: result = result.base
+  of tyGenericInst:
+    result = copyType(t, t.owner, true)
+    for i in 1 .. <result.sonsLen:
+      result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i])
   else:
     if t.kind == tyArray:
       let idxt = t.sons[0]
@@ -238,15 +247,18 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
       if result.kind == tyProc and result.sons[0] != nil:
         if result.sons[0].kind == tyEmpty:
           result.sons[0] = nil
-  
-proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, 
-                           t: PType): PType = 
+
+proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
+                           t: PType): PType =
   var cl: TReplTypeVars
   InitIdTable(cl.symMap)
   copyIdTable(cl.typeMap, pt)
-  cl.info = arg.info
+  cl.info = info
   cl.c = p
-  pushInfoContext(arg.info)
+  pushInfoContext(info)
   result = ReplaceTypeVarsT(cl, t)
   popInfoContext()
 
+template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
+                               t: PType): expr =
+  generateTypeInstance(p, pt, arg.info, t)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 27be1b7d5..20c348f17 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -418,7 +418,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   if a.kind == tyGenericInst and
       skipTypes(f, {tyVar}).kind notin {
         tyGenericBody, tyGenericInvokation,
-        tyGenericParam} + tyTypeClasses:
+        tyGenericInst, tyGenericParam} + tyTypeClasses:
     return typeRel(c, f, lastSon(a))
 
   template bindingRet(res) =
@@ -649,7 +649,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
     if a.kind == tyEmpty: result = isEqual
 
   of tyGenericInst:
-    result = typeRel(c, lastSon(f), a)
+    if a.kind == tyGenericInst:
+      if a.base != f.base: return isNone
+      for i in 1 .. f.sonsLen-2:
+        result = typeRel(c, f.sons[i], a.sons[i])
+        if result == isNone: return
+      result = isGeneric
+    else:
+      result = typeRel(c, lastSon(f), a)
 
   of tyGenericBody:
     if a.kind == tyGenericInst and a.sons[0] == f:
@@ -937,9 +944,9 @@ proc ParamTypesMatchAux(m: var TCandidate, f, argType: PType,
   var
     fMaybeStatic = f.skipTypes({tyDistinct})
     arg = argSemantized
-    c = m.c
     argType = argType
-   
+    c = m.c
+
   if tfHasStatic in fMaybeStatic.flags:
     # XXX: When implicit statics are the default
     # this will be done earlier - we just have to
diff --git a/compiler/types.nim b/compiler/types.nim
index a2869f0da..f0b593996 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1220,8 +1220,9 @@ 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
+proc containsGenericTypeIter(t: PType, closure: PObject): bool =
+  result = t.kind in GenericTypes + tyTypeClasses +
+                     {tyTypeDesc, tyStatic}
 
 proc containsGenericType*(t: PType): bool = 
   result = iterOverType(t, containsGenericTypeIter, nil)