summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorandri lim <jangko128@gmail.com>2018-06-04 22:43:15 +0700
committerAndreas Rumpf <rumpf_a@web.de>2018-06-04 17:43:15 +0200
commit069a53ad4bff8a3160794360227eceb1fc37d8d8 (patch)
tree5194be0f4d8afa40b4598d71b64016967908e847
parent05b447374bb6c8d2d09cee46e4f1fd68f5a8067f (diff)
downloadNim-069a53ad4bff8a3160794360227eceb1fc37d8d8.tar.gz
fixes #7906, array and openarray arg vs. ptr/ref generic (#7909)
* fixes #7906, array and openarray arg vs. ptr/ref generic

* add comment
-rw-r--r--compiler/sem.nim6
-rw-r--r--compiler/types.nim4
-rw-r--r--tests/array/t7818.nim141
3 files changed, 120 insertions, 31 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 55e1f47dc..d56355f14 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -158,11 +158,13 @@ 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, k)
+      result = commonSuperclass(a, b)
       # this will trigger an error later:
       if result.isNil or result == a: return x
       if result == b: return y
-      if k != tyNone:
+      # bug #7906, tyRef/tyPtr + tyGenericInst of ref/ptr object ->
+      # ill-formed AST, no need for additional tyRef/tyPtr
+      if k != tyNone and x.kind != tyGenericInst:
         let r = result
         result = newType(k, r.owner)
         result.addSonSkipIntLit(r)
diff --git a/compiler/types.nim b/compiler/types.nim
index 7f9b8239f..1fab842cc 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, k: TTypeKind): PType =
+proc commonSuperclass*(a, b: PType): PType =
   # quick check: are they the same?
   if sameObjectTypes(a, b): return a
 
@@ -1063,7 +1063,7 @@ proc commonSuperclass*(a, b: PType, k: TTypeKind): PType =
     y = skipTypes(y, skipPtrs)
     if ancestors.contains(y.id):
       # bug #7818, defer the previous skipTypes
-      if k in {tyRef, tyPtr}: t = y
+      if t.kind != tyGenericInst: t = y
       return t
     y = y.sons[0]
 
diff --git a/tests/array/t7818.nim b/tests/array/t7818.nim
index 5d73efec5..4e43bff85 100644
--- a/tests/array/t7818.nim
+++ b/tests/array/t7818.nim
@@ -1,24 +1,5 @@
 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"
----------'''
+  output: "OK"
 """
 
 # bug #7818
@@ -34,12 +15,118 @@ type
   Bike[T] = object of Vehicle[T]
 
 macro peek(n: typed): untyped =
-  echo getTypeImpl(n).treeRepr
-  echo "---------"
+  let val = getTypeImpl(n).treeRepr
+  newLit(val)
+
+block test_t7818:
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_1:
+  proc init(x: typedesc, y: int): ref x =
+    result = new(ref x)
+    result.tire = y
+  
+  var v = init(Vehicle[int], 3)
+  var c = init(Car[int], 4)
+  var b = init(Bike[int], 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_2:
+  var v = Vehicle[int](tire: 3)
+  var c = Car[int](tire: 4)
+  var b = Bike[int](tire: 2)
+
+  let y = peek([c.addr, b.addr, v.addr])
+  let z = peek([v.addr, c.addr, b.addr])
+  doAssert(y == z)
+
+block test_t7906_3:
+  type
+    Animal[T] = object of RootObj
+      hair: T
+    Mammal[T] = object of Animal[T]
+    Monkey[T] = object of Mammal[T]
+
+  var v = Animal[int](hair: 3)
+  var c = Mammal[int](hair: 4)
+  var b = Monkey[int](hair: 2)
+
+  let z = peek([c.addr, b.addr, v.addr])
+  let y = peek([v.addr, c.addr, b.addr])
+  doAssert(y == z)
+  
+type
+  Fruit[T] = ref object of RootObj
+    color: T
+  Apple[T] = ref object of Fruit[T]
+  Banana[T] = ref object of Fruit[T]
+    
+proc testArray[T](x: array[3, Fruit[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.color
+
+proc testOpenArray[T](x: openArray[Fruit[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.color
+    
+block test_t7906_4:
+  var v = Fruit[int](color: 3)
+  var c = Apple[int](color: 4)
+  var b = Banana[int](color: 2)
+
+  let y = peek([c, b, v])
+  let z = peek([v, c, b])
+  doAssert(y == z)
+  
+block test_t7906_5:
+  var a = Fruit[int](color: 1)
+  var b = Apple[int](color: 2)
+  var c = Banana[int](color: 3)
+
+  doAssert(testArray([a, b, c]) == "123")
+  doAssert(testArray([b, c, a]) == "231")
+
+  doAssert(testOpenArray([a, b, c]) == "123")
+  doAssert(testOpenArray([b, c, a]) == "231")
+
+  doAssert(testOpenArray(@[a, b, c]) == "123")
+  doAssert(testOpenArray(@[b, c, a]) == "231")
+
+proc testArray[T](x: array[3, ptr Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+proc testOpenArray[T](x: openArray[ptr Vehicle[T]]): string =
+  result = ""
+  for c in x:
+    result.add $c.tire
+
+block test_t7906_6:
+  var u = Vehicle[int](tire: 1)
+  var v = Bike[int](tire: 2)
+  var w = Car[int](tire: 3)
+  
+  doAssert(testArray([u.addr, v.addr, w.addr]) == "123")
+  doAssert(testArray([w.addr, u.addr, v.addr]) == "312")
+  
+  doAssert(testOpenArray([u.addr, v.addr, w.addr]) == "123")
+  doAssert(testOpenArray([w.addr, u.addr, v.addr]) == "312")
+  
+  doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123")
+  doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312")
+  
+echo "OK"
 
-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])
'>^
185d72e2 ^
ff18572e ^


51bb5f9e ^

ff18572e ^
f44cf86f ^
62dd30ff ^
ef34ddc1 ^
2dacfc82 ^
fbeb107c ^


1814dcdd ^
f7843def ^
e94b604b ^
1e35b76b ^
e0dfe483 ^


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71