fix overloading issue with generic invocation (#15135)
* fix overloading issue with generic alias * add test for inheritance depth
This commit is contained in:
parent
e9df8ebcfd
commit
e194cb41a4
2 changed files with 61 additions and 14 deletions
|
|
@ -579,7 +579,7 @@ proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
if f.isMetaType:
|
if f.isMetaType:
|
||||||
# We are matching a generic proc (as proc param)
|
# We are matching a generic proc (as proc param)
|
||||||
# to another generic type appearing in the proc
|
# to another generic type appearing in the proc
|
||||||
# signature. There is a change that the target
|
# signature. There is a chance that the target
|
||||||
# type is already fully-determined, so we are
|
# type is already fully-determined, so we are
|
||||||
# going to try resolve it
|
# going to try resolve it
|
||||||
if c.call != nil:
|
if c.call != nil:
|
||||||
|
|
@ -1496,7 +1496,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||||
#echo "inferred ", typeToString(inst), " for ", f
|
#echo "inferred ", typeToString(inst), " for ", f
|
||||||
return typeRel(c, inst, a)
|
return typeRel(c, inst, a)
|
||||||
|
|
||||||
var depth = 0
|
|
||||||
if x.kind == tyGenericInvocation or f[0].kind != tyGenericBody:
|
if x.kind == tyGenericInvocation or f[0].kind != tyGenericBody:
|
||||||
#InternalError("typeRel: tyGenericInvocation -> tyGenericInvocation")
|
#InternalError("typeRel: tyGenericInvocation -> tyGenericInvocation")
|
||||||
# simply no match for now:
|
# simply no match for now:
|
||||||
|
|
@ -1510,18 +1509,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||||
# Workaround for regression #4589
|
# Workaround for regression #4589
|
||||||
if f[i].kind != tyTypeDesc: return
|
if f[i].kind != tyTypeDesc: return
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
elif x.kind == tyGenericInst and isGenericSubtype(c, x, f, depth, f) and
|
|
||||||
(x.len - 1 == f.len):
|
|
||||||
# do not recurse here in order to not K bind twice for this code:
|
|
||||||
#
|
|
||||||
# type
|
|
||||||
# BaseFruit[T] = object of RootObj
|
|
||||||
# Banana[T] = object of BaseFruit[uint32] # Concrete type here, not T!
|
|
||||||
# proc setColor[K](self: var BaseFruit[K])
|
|
||||||
# var x: Banana[float64]
|
|
||||||
# x.setColor()
|
|
||||||
c.inheritancePenalty += depth
|
|
||||||
result = isGeneric
|
|
||||||
else:
|
else:
|
||||||
let genericBody = f[0]
|
let genericBody = f[0]
|
||||||
var askip = skippedNone
|
var askip = skippedNone
|
||||||
|
|
|
||||||
|
|
@ -375,3 +375,63 @@ block:
|
||||||
test(c)
|
test(c)
|
||||||
var d: FooBarBazX
|
var d: FooBarBazX
|
||||||
test(d)
|
test(d)
|
||||||
|
|
||||||
|
|
||||||
|
# overloading on tuples with generic alias
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
Foo[F,T] = object
|
||||||
|
exArgs: T
|
||||||
|
FooUn[F,T] = Foo[F,tuple[a:T]]
|
||||||
|
FooBi[F,T1,T2] = Foo[F,tuple[a:T1,b:T2]]
|
||||||
|
|
||||||
|
proc foo1[F,T](x: Foo[F,tuple[a:T]]): int = 1
|
||||||
|
proc foo1[F,T1,T2](x: Foo[F,tuple[a:T1,b:T2]]): int = 2
|
||||||
|
proc foo2[F,T](x: FooUn[F,T]): int = 1
|
||||||
|
proc foo2[F,T1,T2](x: FooBi[F,T1,T2]):int = 2
|
||||||
|
|
||||||
|
template bar1[F,T](x: Foo[F,tuple[a:T]]): int = 1
|
||||||
|
template bar1[F,T1,T2](x: Foo[F,tuple[a:T1,b:T2]]): int = 2
|
||||||
|
template bar2[F,T](x: FooUn[F,T]): int = 1
|
||||||
|
template bar2[F,T1,T2](x: FooBi[F,T1,T2]): int = 2
|
||||||
|
|
||||||
|
proc test(x: any, n: int) =
|
||||||
|
doAssert(foo1(x) == n)
|
||||||
|
doAssert(foo2(x) == n)
|
||||||
|
doAssert(bar1(x) == n)
|
||||||
|
doAssert(bar2(x) == n)
|
||||||
|
|
||||||
|
var a: Foo[int, tuple[a:int]]
|
||||||
|
test(a, 1)
|
||||||
|
var b: FooUn[int, int]
|
||||||
|
test(b, 1)
|
||||||
|
var c: Foo[int, tuple[a:int,b:int]]
|
||||||
|
test(c, 2)
|
||||||
|
var d: FooBi[int, int, int]
|
||||||
|
test(d, 2)
|
||||||
|
|
||||||
|
|
||||||
|
# inheritance depth
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
Foo[T] = object of RootObj
|
||||||
|
x: T
|
||||||
|
Bar[T] = object of Foo[T]
|
||||||
|
y: T
|
||||||
|
Baz[T] = object of Bar[T]
|
||||||
|
z: T
|
||||||
|
|
||||||
|
template t0[T](x: Foo[T]): int = 0
|
||||||
|
template t0[T](x: Bar[T]): int = 1
|
||||||
|
proc p0[T](x: Foo[T]): int = 0
|
||||||
|
proc p0[T](x: Bar[T]): int = 1
|
||||||
|
|
||||||
|
var a: Foo[int]
|
||||||
|
var b: Bar[int]
|
||||||
|
var c: Baz[int]
|
||||||
|
doAssert(t0(a) == 0)
|
||||||
|
doAssert(t0(b) == 1)
|
||||||
|
doAssert(t0(c) == 1)
|
||||||
|
doAssert(p0(a) == 0)
|
||||||
|
doAssert(p0(b) == 1)
|
||||||
|
doAssert(p0(c) == 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue