integrate the logic of fixupProcType into ReplaceTypeVars
This commit is contained in:
parent
66a2556525
commit
72291875bf
10 changed files with 108 additions and 74 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue