fixes #5231 inheriting from partial specialized generic object (#5538)

This commit is contained in:
andri lim 2017-03-15 13:59:34 +07:00 • committed by Andreas Rumpf
commit ebb15505dd
2 changed files with 59 additions and 9 deletions

View file

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