integrate the logic of fixupProcType into ReplaceTypeVars

This commit is contained in:
Zahary Karadjov 2013-12-29 16:08:33 +02:00
commit 72291875bf
10 changed files with 108 additions and 74 deletions

View file

@ -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

View file

@ -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,

View file

@ -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:

View file

@ -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})

View file

@ -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)

View file

@ -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

View file

@ -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)