* fixes #7906, array and openarray arg vs. ptr/ref generic * add comment
This commit is contained in:
parent
05b447374b
commit
069a53ad4b
3 changed files with 120 additions and 31 deletions
|
|
@ -158,11 +158,13 @@ proc commonType*(x, y: PType): PType =
|
||||||
a = a.lastSon.skipTypes({tyGenericInst})
|
a = a.lastSon.skipTypes({tyGenericInst})
|
||||||
b = b.lastSon.skipTypes({tyGenericInst})
|
b = b.lastSon.skipTypes({tyGenericInst})
|
||||||
if a.kind == tyObject and b.kind == tyObject:
|
if a.kind == tyObject and b.kind == tyObject:
|
||||||
result = commonSuperclass(a, b, k)
|
result = commonSuperclass(a, b)
|
||||||
# this will trigger an error later:
|
# this will trigger an error later:
|
||||||
if result.isNil or result == a: return x
|
if result.isNil or result == a: return x
|
||||||
if result == b: return y
|
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
|
let r = result
|
||||||
result = newType(k, r.owner)
|
result = newType(k, r.owner)
|
||||||
result.addSonSkipIntLit(r)
|
result.addSonSkipIntLit(r)
|
||||||
|
|
|
||||||
|
|
@ -1043,7 +1043,7 @@ proc inheritanceDiff*(a, b: PType): int =
|
||||||
inc(result)
|
inc(result)
|
||||||
result = high(int)
|
result = high(int)
|
||||||
|
|
||||||
proc commonSuperclass*(a, b: PType, k: TTypeKind): PType =
|
proc commonSuperclass*(a, b: PType): PType =
|
||||||
# quick check: are they the same?
|
# quick check: are they the same?
|
||||||
if sameObjectTypes(a, b): return a
|
if sameObjectTypes(a, b): return a
|
||||||
|
|
||||||
|
|
@ -1063,7 +1063,7 @@ proc commonSuperclass*(a, b: PType, k: TTypeKind): PType =
|
||||||
y = skipTypes(y, skipPtrs)
|
y = skipTypes(y, skipPtrs)
|
||||||
if ancestors.contains(y.id):
|
if ancestors.contains(y.id):
|
||||||
# bug #7818, defer the previous skipTypes
|
# bug #7818, defer the previous skipTypes
|
||||||
if k in {tyRef, tyPtr}: t = y
|
if t.kind != tyGenericInst: t = y
|
||||||
return t
|
return t
|
||||||
y = y.sons[0]
|
y = y.sons[0]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
msg: '''BracketExpr
|
output: "OK"
|
||||||
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
|
# bug #7818
|
||||||
|
|
@ -34,12 +15,118 @@ type
|
||||||
Bike[T] = object of Vehicle[T]
|
Bike[T] = object of Vehicle[T]
|
||||||
|
|
||||||
macro peek(n: typed): untyped =
|
macro peek(n: typed): untyped =
|
||||||
echo getTypeImpl(n).treeRepr
|
let val = getTypeImpl(n).treeRepr
|
||||||
echo "---------"
|
newLit(val)
|
||||||
|
|
||||||
|
block test_t7818:
|
||||||
var v = Vehicle[int](tire: 3)
|
var v = Vehicle[int](tire: 3)
|
||||||
var c = Car[int](tire: 4)
|
var c = Car[int](tire: 4)
|
||||||
var b = Bike[int](tire: 2)
|
var b = Bike[int](tire: 2)
|
||||||
|
|
||||||
peek([c, b, v])
|
let y = peek([c, b, v])
|
||||||
peek([v, c, b])
|
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"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue