diff options
author | andri lim <jangko128@gmail.com> | 2017-03-15 13:59:34 +0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-03-15 07:59:34 +0100 |
commit | ebb15505dd610074bb8900e6bacd775d6e064a7f (patch) | |
tree | 681f4b27633a6ad04cb32ab39287927c52a8412d | |
parent | 93753926f5db8fa0cd94afa7e0783bba23949441 (diff) | |
download | Nim-ebb15505dd610074bb8900e6bacd775d6e064a7f.tar.gz |
fixes #5231 inheriting from partial specialized generic object (#5538)
-rw-r--r-- | compiler/semtypes.nim | 25 | ||||
-rw-r--r-- | tests/types/tinheritpartialgeneric.nim | 43 |
2 files changed, 59 insertions, 9 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index bffa12f33..cb3d24a76 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -623,8 +623,8 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, styleCheckDef(f) if a.kind != nkEmpty: addSon(father, a) of nkSym: - # this branch only valid during generic object - # with parameterized parent second check. + # This branch only valid during generic object + # inherited from generic/partial specialized parent second check. # There is no branch validity check here if containsOrIncl(check, n.sym.name.id): localError(n.info, errAttemptToRedefine, n.sym.name.s) @@ -680,7 +680,12 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = localError(n.info, errIllegalRecursionInTypeX, "object") else: var concreteBase = skipGenericInvocation(base) - if concreteBase.kind in {tyObject, tyGenericParam} and tfFinal notin concreteBase.flags: + if concreteBase.kind in {tyObject, tyGenericParam, + tyGenericInvocation} and tfFinal notin concreteBase.flags: + # we only check fields duplication of object inherited from + # concrete object. If inheriting from generic object or partial + # specialized object, there will be second check after instantiation + # located in semGeneric. if concreteBase.kind == tyObject: addInheritedFields(c, check, pos, concreteBase) else: @@ -1054,14 +1059,16 @@ proc semGenericParamInInvocation(c: PContext, n: PNode): PType = result = semTypeNode(c, n, nil) proc semObjectTypeForInheritedGenericInst(c: PContext, n: PNode, t: PType) = - var check = initIntSet() - var realBase = t.sons[0] - var pos = 0 - var base = skipTypesOrNil(realBase, skipPtrs) + var + check = initIntSet() + pos = 0 + let + realBase = t.sons[0] + base = skipTypesOrNil(realBase, skipPtrs) if base.isNil: localError(n.info, errIllegalRecursionInTypeX, "object") else: - var concreteBase = skipGenericInvocation(base) + let concreteBase = skipGenericInvocation(base) if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags: addInheritedFields(c, check, pos, concreteBase) else: @@ -1133,7 +1140,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = allowMetaTypes = false) # special check for generic object with - # parameterized parent + # generic/partial specialized parent let tx = result.skipTypes(abstractPtrs) if tx != result and tx.kind == tyObject and tx.sons[0] != nil: semObjectTypeForInheritedGenericInst(c, n, tx) diff --git a/tests/types/tinheritpartialgeneric.nim b/tests/types/tinheritpartialgeneric.nim new file mode 100644 index 000000000..a00df26fa --- /dev/null +++ b/tests/types/tinheritpartialgeneric.nim @@ -0,0 +1,43 @@ +discard """ + output: '''(c: hello, a: 10, b: 12.0) +(a: 15.5, b: hello) +(a: 11.75, b: 123)''' +""" + +# bug #5231 +# generic object inheriting from +# partial specialized generic object +type + Curve1[T, X] = object of RootObj + a: T + b: X + + Curve2[T] = Curve1[T, float64] + + Curve3[T] = object of Curve2[T] + c: string + + Curve4[T] = Curve1[float64, T] + + Curve5[T] = object of Curve4[T] + + Curve6[T] = object of T + +var x: Curve3[int] +x.a = 10 +x.b = 12.0 +x.c = "hello" + +echo x + +var y: Curve5[string] +y.b = "hello" +y.a = 15.5 + +echo y + +var z: Curve6[Curve4[int]] +z.a = 11.75 +z.b = 123 + +echo z \ No newline at end of file |