summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorandri lim <jangko128@gmail.com>2018-05-29 14:38:52 +0700
committerAndreas Rumpf <rumpf_a@web.de>2018-05-29 09:38:52 +0200
commit25a41d5d90c707e8d926308c495c95e2cd13d984 (patch)
treef1b6c7fc83df9891fa5dc840476d822256d682ae
parenta075a912cfaba685ad1ba9e41d046265fdf104b8 (diff)
downloadNim-25a41d5d90c707e8d926308c495c95e2cd13d984.tar.gz
fixes #7818, correct internal representation of generic objects array construction (#7824)
* defer skiptypes
* defer skiptypes for tyRef & tyPtr
* remove unneeded skipTypes
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/types.nim8
-rw-r--r--tests/array/t7818.nim45
3 files changed, 52 insertions, 3 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 7bccf1556..55e1f47dc 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -158,7 +158,7 @@ proc commonType*(x, y: PType): PType =
       a = a.lastSon.skipTypes({tyGenericInst})
       b = b.lastSon.skipTypes({tyGenericInst})
     if a.kind == tyObject and b.kind == tyObject:
-      result = commonSuperclass(a, b)
+      result = commonSuperclass(a, b, k)
       # this will trigger an error later:
       if result.isNil or result == a: return x
       if result == b: return y
diff --git a/compiler/types.nim b/compiler/types.nim
index b5f4fbf54..7f9b8239f 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1043,7 +1043,7 @@ proc inheritanceDiff*(a, b: PType): int =
     inc(result)
   result = high(int)
 
-proc commonSuperclass*(a, b: PType): PType =
+proc commonSuperclass*(a, b: PType, k: TTypeKind): PType =
   # quick check: are they the same?
   if sameObjectTypes(a, b): return a
 
@@ -1059,8 +1059,12 @@ proc commonSuperclass*(a, b: PType): PType =
     x = x.sons[0]
   var y = b
   while y != nil:
+    var t = y # bug #7818, save type before skip
     y = skipTypes(y, skipPtrs)
-    if ancestors.contains(y.id): return y
+    if ancestors.contains(y.id):
+      # bug #7818, defer the previous skipTypes
+      if k in {tyRef, tyPtr}: t = y
+      return t
     y = y.sons[0]
 
 type
diff --git a/tests/array/t7818.nim b/tests/array/t7818.nim
new file mode 100644
index 000000000..5d73efec5
--- /dev/null
+++ b/tests/array/t7818.nim
@@ -0,0 +1,45 @@
+discard """
+  msg: '''BracketExpr
+  Sym "array"
+  Infix
+    Ident ".."
+    IntLit 0
+    IntLit 2
+  BracketExpr
+    Sym "Vehicle"
+    Sym "int"
+---------
+BracketExpr
+  Sym "array"
+  Infix
+    Ident ".."
+    IntLit 0
+    IntLit 2
+  BracketExpr
+    Sym "Vehicle"
+    Sym "int"
+---------'''
+"""
+
+# bug #7818
+# this is not a macro bug, but array construction bug
+# I use macro to avoid object slicing
+# see #7712 and #7637
+import macros
+
+type
+  Vehicle[T] = object of RootObj
+    tire: T
+  Car[T] = object of Vehicle[T]
+  Bike[T] = object of Vehicle[T]
+
+macro peek(n: typed): untyped =
+  echo getTypeImpl(n).treeRepr
+  echo "---------"
+
+var v = Vehicle[int](tire: 3)
+var c = Car[int](tire: 4)
+var b = Bike[int](tire: 2)
+
+peek([c, b, v])
+peek([v, c, b])