mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
* fixes #7906, array and openarray arg vs. ptr/ref generic * add comment
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user