fixes #7906, array and openarray arg vs. ptr/ref generic (#7909)

* fixes #7906, array and openarray arg vs. ptr/ref generic

* add comment
This commit is contained in:
andri lim
2018-06-04 22:43:15 +07:00
committed by Andreas Rumpf
parent 05b447374b
commit 069a53ad4b
3 changed files with 120 additions and 31 deletions

View File

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

View File

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

View File

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