summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorandri lim <jangko128@gmail.com>2017-03-15 13:59:34 +0700
committerAndreas Rumpf <rumpf_a@web.de>2017-03-15 07:59:34 +0100
commitebb15505dd610074bb8900e6bacd775d6e064a7f (patch)
tree681f4b27633a6ad04cb32ab39287927c52a8412d
parent93753926f5db8fa0cd94afa7e0783bba23949441 (diff)
downloadNim-ebb15505dd610074bb8900e6bacd775d6e064a7f.tar.gz
fixes #5231 inheriting from partial specialized generic object (#5538)
-rw-r--r--compiler/semtypes.nim25
-rw-r--r--tests/types/tinheritpartialgeneric.nim43
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