parent
976095c894
commit
0ff1190fe7
6 changed files with 184 additions and 2 deletions
|
|
@ -622,6 +622,13 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
else: addSon(a, newSymNode(f))
|
else: addSon(a, newSymNode(f))
|
||||||
styleCheckDef(f)
|
styleCheckDef(f)
|
||||||
if a.kind != nkEmpty: addSon(father, a)
|
if a.kind != nkEmpty: addSon(father, a)
|
||||||
|
of nkSym:
|
||||||
|
# this branch only valid during generic object
|
||||||
|
# with parameterized 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)
|
||||||
|
addSon(father, n)
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
|
|
||||||
|
|
@ -673,7 +680,8 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
localError(n.info, errIllegalRecursionInTypeX, "object")
|
localError(n.info, errIllegalRecursionInTypeX, "object")
|
||||||
else:
|
else:
|
||||||
var concreteBase = skipGenericInvocation(base)
|
var concreteBase = skipGenericInvocation(base)
|
||||||
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
if concreteBase.kind in {tyObject, tyGenericParam} and tfFinal notin concreteBase.flags:
|
||||||
|
if concreteBase.kind == tyObject:
|
||||||
addInheritedFields(c, check, pos, concreteBase)
|
addInheritedFields(c, check, pos, concreteBase)
|
||||||
else:
|
else:
|
||||||
if concreteBase.kind != tyError:
|
if concreteBase.kind != tyError:
|
||||||
|
|
@ -1045,6 +1053,23 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
|
||||||
proc semGenericParamInInvocation(c: PContext, n: PNode): PType =
|
proc semGenericParamInInvocation(c: PContext, n: PNode): PType =
|
||||||
result = semTypeNode(c, n, nil)
|
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)
|
||||||
|
if base.isNil:
|
||||||
|
localError(n.info, errIllegalRecursionInTypeX, "object")
|
||||||
|
else:
|
||||||
|
var concreteBase = skipGenericInvocation(base)
|
||||||
|
if concreteBase.kind == tyObject and tfFinal notin concreteBase.flags:
|
||||||
|
addInheritedFields(c, check, pos, concreteBase)
|
||||||
|
else:
|
||||||
|
if concreteBase.kind != tyError:
|
||||||
|
localError(n.info, errInheritanceOnlyWithNonFinalObjects)
|
||||||
|
var newf = newNodeI(nkRecList, n.info)
|
||||||
|
semRecordNodeAux(c, t.n, check, pos, newf, t)
|
||||||
|
|
||||||
proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
if s.typ == nil:
|
if s.typ == nil:
|
||||||
localError(n.info, "cannot instantiate the '$1' $2" %
|
localError(n.info, "cannot instantiate the '$1' $2" %
|
||||||
|
|
@ -1107,6 +1132,12 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
result = instGenericContainer(c, n.info, result,
|
result = instGenericContainer(c, n.info, result,
|
||||||
allowMetaTypes = false)
|
allowMetaTypes = false)
|
||||||
|
|
||||||
|
# special check for generic object with
|
||||||
|
# parameterized parent
|
||||||
|
let tx = result.skipTypes(abstractPtrs)
|
||||||
|
if tx != result and tx.kind == tyObject and tx.sons[0] != nil:
|
||||||
|
semObjectTypeForInheritedGenericInst(c, n, tx)
|
||||||
|
|
||||||
proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
|
proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
|
||||||
var n = semExprWithType(c, n, {efDetermineType})
|
var n = semExprWithType(c, n, {efDetermineType})
|
||||||
if n.typ.kind == tyTypeDesc:
|
if n.typ.kind == tyTypeDesc:
|
||||||
|
|
|
||||||
15
tests/types/tparameterizedparent0.nim
Normal file
15
tests/types/tparameterizedparent0.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
discard """
|
||||||
|
file: "tparameterizedparent0.nim"
|
||||||
|
line: 14
|
||||||
|
errormsg: "inheritance only works with non-final objects"
|
||||||
|
"""
|
||||||
|
# bug #5264
|
||||||
|
type
|
||||||
|
Kapal* = enum
|
||||||
|
Besar
|
||||||
|
|
||||||
|
Apple[T] = object of T
|
||||||
|
color: int
|
||||||
|
|
||||||
|
var x = Apple[Kapal](color: 13)
|
||||||
|
echo x
|
||||||
14
tests/types/tparameterizedparent1.nim
Normal file
14
tests/types/tparameterizedparent1.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
discard """
|
||||||
|
file: "tparameterizedparent1.nim"
|
||||||
|
line: 14
|
||||||
|
errormsg: "inheritance only works with non-final objects"
|
||||||
|
"""
|
||||||
|
# bug #5264
|
||||||
|
type
|
||||||
|
FruitBase = object
|
||||||
|
color: int
|
||||||
|
|
||||||
|
Apple[T] = object of T
|
||||||
|
width: int
|
||||||
|
|
||||||
|
var x: Apple[FruitBase]
|
||||||
77
tests/types/tparameterizedparent2.nim
Normal file
77
tests/types/tparameterizedparent2.nim
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
discard """
|
||||||
|
output: '''(width: 11, color: 13)
|
||||||
|
(width: 15, weight: 13, taste: 11, color: 14)
|
||||||
|
(width: 17, color: 16)
|
||||||
|
(width: 12.0, taste: yummy, color: 13)
|
||||||
|
(width: 0, tast_e: 0.0, kind: Smooth, skin: 1.5, color: 12)'''
|
||||||
|
"""
|
||||||
|
# bug #5264
|
||||||
|
type
|
||||||
|
Texture = enum
|
||||||
|
Smooth
|
||||||
|
Coarse
|
||||||
|
|
||||||
|
FruitBase = object of RootObj
|
||||||
|
color: int
|
||||||
|
|
||||||
|
Level2Fruit = object of FruitBase
|
||||||
|
taste: int
|
||||||
|
|
||||||
|
AppleBanana = object of Level2Fruit
|
||||||
|
weight: int
|
||||||
|
|
||||||
|
BaseFruit[T] = object of RootObj
|
||||||
|
color: T
|
||||||
|
|
||||||
|
Apple[T] = object of T
|
||||||
|
width: int
|
||||||
|
|
||||||
|
Peach[X, T, Y] = object of T
|
||||||
|
width: X
|
||||||
|
taste: Y
|
||||||
|
|
||||||
|
Lemon[T] = object of T
|
||||||
|
width: int
|
||||||
|
tast_e: float64
|
||||||
|
case kind: Texture
|
||||||
|
of Smooth:
|
||||||
|
skin: float64
|
||||||
|
of Coarse:
|
||||||
|
grain: int
|
||||||
|
|
||||||
|
var x: Apple[FruitBase]
|
||||||
|
x.color = 13
|
||||||
|
x.width = 11
|
||||||
|
echo x
|
||||||
|
|
||||||
|
proc setColor(self: var FruitBase, c: int) =
|
||||||
|
self.color = c
|
||||||
|
|
||||||
|
proc setTaste[T](self: var Apple[T], c: int) =
|
||||||
|
self.taste = c
|
||||||
|
|
||||||
|
#proc setColor[T](self: var BaseFruit[T], c: int) =
|
||||||
|
# self.color = c
|
||||||
|
|
||||||
|
var y: Apple[AppleBanana]
|
||||||
|
y.setColor(14)
|
||||||
|
y.setTaste(11)
|
||||||
|
y.weight = 13
|
||||||
|
y.width = 15
|
||||||
|
echo y
|
||||||
|
|
||||||
|
var w: Apple[BaseFruit[int]]
|
||||||
|
w.width = 17
|
||||||
|
w.color = 16
|
||||||
|
echo w
|
||||||
|
|
||||||
|
var z: Peach[float64, BaseFruit[int], string]
|
||||||
|
z.width = 12
|
||||||
|
z.taste = "yummy"
|
||||||
|
#z.setColor(13) #this trigger other bug
|
||||||
|
z.color = 13
|
||||||
|
echo z
|
||||||
|
|
||||||
|
var k = Lemon[FruitBase](kind: Smooth, skin: 1.5)
|
||||||
|
k.setColor(12)
|
||||||
|
echo k
|
||||||
15
tests/types/tparameterizedparent3.nim
Normal file
15
tests/types/tparameterizedparent3.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
discard """
|
||||||
|
file: "tparameterizedparent3.nim"
|
||||||
|
line: 13
|
||||||
|
errormsg: "redefinition of 'color'"
|
||||||
|
"""
|
||||||
|
# bug #5264
|
||||||
|
type
|
||||||
|
FruitBase = object of RootObj
|
||||||
|
color: int
|
||||||
|
|
||||||
|
Apple[T] = object of T
|
||||||
|
width: int
|
||||||
|
color: int
|
||||||
|
|
||||||
|
var x: Apple[FruitBase]
|
||||||
30
tests/types/tparameterizedparent4.nim
Normal file
30
tests/types/tparameterizedparent4.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
discard """
|
||||||
|
file: "tparameterizedparent4.nim"
|
||||||
|
line: 23
|
||||||
|
errormsg: "redefinition of 'grain'"
|
||||||
|
"""
|
||||||
|
# bug #5264
|
||||||
|
type
|
||||||
|
Texture = enum
|
||||||
|
Smooth
|
||||||
|
Coarse
|
||||||
|
|
||||||
|
FruitBase = object of RootObj
|
||||||
|
color: int
|
||||||
|
grain: string
|
||||||
|
|
||||||
|
Apple[T] = object of T
|
||||||
|
width: int
|
||||||
|
tast_e: float64
|
||||||
|
case kind: Texture
|
||||||
|
of Smooth:
|
||||||
|
skin: float64
|
||||||
|
of Coarse:
|
||||||
|
grain: int
|
||||||
|
|
||||||
|
proc setColor(self: var FruitBase, c: int) =
|
||||||
|
self.color = c
|
||||||
|
|
||||||
|
var x = Apple[FruitBase](kind: Smooth, skin: 1.5)
|
||||||
|
x.setColor(14)
|
||||||
|
echo x
|
||||||
Loading…
Add table
Add a link
Reference in a new issue