lift generic parameters from concrete composite type classes
This commit is contained in:
parent
a27eb51535
commit
a59f13b00d
5 changed files with 40 additions and 25 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue