lift generic parameters from concrete composite type classes

This commit is contained in:
Zahary Karadjov 2013-12-28 12:50:45 +02:00
commit a59f13b00d
5 changed files with 40 additions and 25 deletions

View file

@ -204,6 +204,8 @@ proc fixupProcType(c: PContext, genericType: PType,
result = result.sons[0] result = result.sons[0]
of tyStatic: of tyStatic:
result = inst.concreteTypes[genericType.sym.position] result = inst.concreteTypes[genericType.sym.position]
of tyGenericInst:
result = fixupProcType(c, result.lastSon, inst)
of tyOpenArray, tyArray, tySet, tySequence, tyTuple, tyProc, of tyOpenArray, tyArray, tySet, tySequence, tyTuple, tyProc,
tyPtr, tyVar, tyRef, tyOrdinal, tyRange, tyVarargs: tyPtr, tyVar, tyRef, tyOrdinal, tyRange, tyVarargs:
if genericType.sons == nil: return if genericType.sons == nil: return
@ -234,6 +236,7 @@ proc fixupProcType(c: PContext, genericType: PType,
continue continue
result.sons[head] = changed result.sons[head] = changed
result.size = 0
if result.n != nil: if result.n != nil:
if result.n.kind == nkRecList: if result.n.kind == nkRecList:

View file

@ -665,6 +665,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if lifted != nil: if lifted != nil:
paramType.sons[i] = lifted paramType.sons[i] = lifted
result = paramType result = paramType
of tyGenericBody: of tyGenericBody:
result = newTypeS(tyGenericInvokation, c) result = newTypeS(tyGenericInvokation, c)
result.rawAddSon(paramType) result.rawAddSon(paramType)
@ -674,6 +675,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
allowMetaTypes = true) allowMetaTypes = true)
result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
result = addImplicitGeneric(result) result = addImplicitGeneric(result)
of tyGenericInst: of tyGenericInst:
for i in 1 .. (paramType.sons.len - 2): for i in 1 .. (paramType.sons.len - 2):
var lifted = liftingWalk(paramType.sons[i]) var lifted = liftingWalk(paramType.sons[i])
@ -681,21 +683,22 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
paramType.sons[i] = lifted paramType.sons[i] = lifted
result = paramType result = paramType
if result == nil: let liftBody = liftingWalk(paramType.lastSon)
result = liftingWalk(paramType.lastSon) if liftBody != nil: result = liftBody
else:
result.kind = tyGenericInvokation
result.sons.setLen(result.sons.len - 1)
of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false)) result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
of tyExpr: of tyExpr:
result = addImplicitGeneric(newTypeS(tyGenericParam, c)) result = addImplicitGeneric(newTypeS(tyGenericParam, c))
of tyGenericParam: of tyGenericParam:
if tfGenericTypeParam in paramType.flags and false: if tfGenericTypeParam in paramType.flags and false:
if paramType.sonsLen > 0: if paramType.sonsLen > 0:
result = liftingWalk(paramType.lastSon) result = liftingWalk(paramType.lastSon)
else: else:
result = addImplicitGeneric(newTypeS(tyGenericParam, c)) result = addImplicitGeneric(newTypeS(tyGenericParam, c))
else: nil else: nil
# result = liftingWalk(paramType) # result = liftingWalk(paramType)

View file

@ -24,7 +24,7 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) =
LocalError(info, errInvalidPragmaX, "acyclic") LocalError(info, errInvalidPragmaX, "acyclic")
elif t.kind == tyVar and t.sons[0].kind == tyVar: elif t.kind == tyVar and t.sons[0].kind == tyVar:
LocalError(info, errVarVarTypeNotAllowed) LocalError(info, errVarVarTypeNotAllowed)
elif computeSize(t) < 0: elif computeSize(t) == szIllegalRecursion:
LocalError(info, errIllegalRecursionInTypeX, typeToString(t)) LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
when false: when false:
if t.kind == tyObject and t.sons[0] != nil: if t.kind == tyObject and t.sons[0] != nil:
@ -170,7 +170,8 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
# recursive instantions: # recursive instantions:
result = newType(tyGenericInst, t.sons[0].owner) result = newType(tyGenericInst, t.sons[0].owner)
result.rawAddSon(header.sons[0]) result.rawAddSon(header.sons[0])
cacheTypeInst(result) if not cl.allowMetaTypes:
cacheTypeInst(result)
for i in countup(1, sonsLen(t) - 1): for i in countup(1, sonsLen(t) - 1):
var x = replaceTypeVarsT(cl, t.sons[i]) var x = replaceTypeVarsT(cl, t.sons[i])

View file

@ -1098,18 +1098,22 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt =
a = 1 a = 1
result = - 1 result = - 1
const
szIllegalRecursion* = -2
szUnknownSize* = -1
proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
var res, maxAlign, length, currOffset: biggestInt var res, maxAlign, length, currOffset: biggestInt
if typ.size == - 2: if typ.size == szIllegalRecursion:
# we are already computing the size of the type # we are already computing the size of the type
# --> illegal recursion in type # --> illegal recursion in type
return - 2 return szIllegalRecursion
if typ.size >= 0: if typ.size >= 0:
# size already computed # size already computed
result = typ.size result = typ.size
a = typ.align a = typ.align
return return
typ.size = - 2 # mark as being computed typ.size = szIllegalRecursion # mark as being computed
case typ.kind case typ.kind
of tyInt, tyUInt: of tyInt, tyUInt:
result = IntSize result = IntSize
@ -1196,7 +1200,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
of tyProxy: result = 1 of tyProxy: result = 1
else: else:
#internalError("computeSizeAux()") #internalError("computeSizeAux()")
result = - 1 result = szUnknownSize
typ.size = result typ.size = result
typ.align = int(a) typ.align = int(a)
@ -1213,7 +1217,6 @@ proc getSize(typ: PType): biggestInt =
result = computeSize(typ) result = computeSize(typ)
if result < 0: InternalError("getSize: " & $typ.kind) if result < 0: InternalError("getSize: " & $typ.kind)
proc containsGenericTypeIter(t: PType, closure: PObject): bool = proc containsGenericTypeIter(t: PType, closure: PObject): bool =
result = t.kind in GenericTypes result = t.kind in GenericTypes

View file

@ -13,18 +13,23 @@ type
TUserClass = int|string TUserClass = int|string
# TBaz = TBar[TUserClass] TBaz = TBar[TUserClass]
var var
vfoo: TFoo[int, string] vfoo: TFoo[int, string]
vbar: TFoo[string, string] vbar: TFoo[string, string]
vbaz: TFoo[int, int]
vnotbaz: TFoo[TObject, TObject]
proc foo(x: TFoo) = echo "foo" proc foo(x: TFoo) = echo "foo"
proc bar(x: TBar) = echo "bar" proc bar(x: TBar) = echo "bar"
# proc baz(x: TBaz) = echo "baz" proc baz(x: TBaz) = echo "baz"
accept(foo(vfoo)) accept foo(vfoo)
accept(bar(vbar)) accept bar(vbar)
# baz vbar accept baz(vbar)
reject(bar(vfoo)) accept baz(vbaz)
reject baz(vnotbaz)
reject bar(vfoo)