fixes #6526
This commit is contained in:
parent
8c94a00e02
commit
9c00f6decd
3 changed files with 36 additions and 15 deletions
|
|
@ -14,3 +14,5 @@
|
||||||
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
|
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
|
||||||
- `reExtended` is no longer default for the `re` constructor in the `re`
|
- `reExtended` is no longer default for the `re` constructor in the `re`
|
||||||
module.
|
module.
|
||||||
|
- The overloading rules changed slightly so that constrained generics are
|
||||||
|
preferred over unconstrained generics. (Bug #6526)
|
||||||
|
|
|
||||||
|
|
@ -1452,8 +1452,13 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
of tyOr:
|
of tyOr:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
result = isNone
|
result = isNone
|
||||||
|
let oldInheritancePenalty = c.inheritancePenalty
|
||||||
|
var maxInheritance = 0
|
||||||
for branch in f.sons:
|
for branch in f.sons:
|
||||||
|
c.inheritancePenalty = 0
|
||||||
let x = typeRel(c, branch, aOrig)
|
let x = typeRel(c, branch, aOrig)
|
||||||
|
maxInheritance = max(maxInheritance, c.inheritancePenalty)
|
||||||
|
|
||||||
# 'or' implies maximum matching result:
|
# 'or' implies maximum matching result:
|
||||||
if x > result: result = x
|
if x > result: result = x
|
||||||
if result >= isSubtype:
|
if result >= isSubtype:
|
||||||
|
|
@ -1461,6 +1466,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
bindingRet result
|
bindingRet result
|
||||||
else:
|
else:
|
||||||
result = isNone
|
result = isNone
|
||||||
|
c.inheritancePenalty = oldInheritancePenalty + maxInheritance
|
||||||
|
|
||||||
of tyNot:
|
of tyNot:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
|
|
@ -1551,21 +1557,19 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
result = isNone
|
result = isNone
|
||||||
else:
|
else:
|
||||||
if f.sonsLen > 0 and f.sons[0].kind != tyNone:
|
if f.sonsLen > 0 and f.sons[0].kind != tyNone:
|
||||||
when false:
|
let oldInheritancePenalty = c.inheritancePenalty
|
||||||
let oldInheritancePenalty = c.inheritancePenalty
|
|
||||||
result = typeRel(c, f.lastSon, a, flags + {trDontBind})
|
result = typeRel(c, f.lastSon, a, flags + {trDontBind})
|
||||||
if doBind and result notin {isNone, isGeneric}:
|
if doBind and result notin {isNone, isGeneric}:
|
||||||
let concrete = concreteType(c, a)
|
let concrete = concreteType(c, a)
|
||||||
if concrete == nil: return isNone
|
if concrete == nil: return isNone
|
||||||
put(c, f, concrete)
|
put(c, f, concrete)
|
||||||
when false:
|
# bug #6526
|
||||||
# bug #6526
|
if result in {isEqual, isSubtype}:
|
||||||
if result in {isEqual, isSubtype}:
|
# 'T: Class' is a *better* match than just 'T'
|
||||||
# 'T: Class' is a *better* match than just 'T'
|
# but 'T: Subclass' is even better:
|
||||||
# but 'T: Subclass' is even better:
|
c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty -
|
||||||
c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty -
|
100 * ord(result == isEqual)
|
||||||
100 * ord(result == isEqual)
|
result = isGeneric
|
||||||
result = isGeneric
|
|
||||||
else:
|
else:
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ discard """
|
||||||
output: '''Version 2 was called.
|
output: '''Version 2 was called.
|
||||||
This has the highest precedence.
|
This has the highest precedence.
|
||||||
This has the second-highest precedence.
|
This has the second-highest precedence.
|
||||||
This has the lowest precedence.'''
|
This has the lowest precedence.
|
||||||
|
baseobj ==
|
||||||
|
true'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# bug #2220
|
# bug #2220
|
||||||
|
|
@ -26,13 +28,13 @@ template testPred(a: untyped) =
|
||||||
type SomeA = A|A # A hack to make "A" a typeclass.
|
type SomeA = A|A # A hack to make "A" a typeclass.
|
||||||
|
|
||||||
when a >= 3:
|
when a >= 3:
|
||||||
proc p[X](x: X) =
|
|
||||||
echo "This has the highest precedence."
|
|
||||||
when a >= 2:
|
|
||||||
proc p[X: A](x: X) =
|
proc p[X: A](x: X) =
|
||||||
|
echo "This has the highest precedence."
|
||||||
|
when a == 2:
|
||||||
|
proc p[X: SomeA](x: X) =
|
||||||
echo "This has the second-highest precedence."
|
echo "This has the second-highest precedence."
|
||||||
when a >= 1:
|
when a >= 1:
|
||||||
proc p[X: SomeA](x: X) =
|
proc p[X](x: X) =
|
||||||
echo "This has the lowest precedence."
|
echo "This has the lowest precedence."
|
||||||
|
|
||||||
p(B())
|
p(B())
|
||||||
|
|
@ -40,3 +42,16 @@ template testPred(a: untyped) =
|
||||||
testPred(3)
|
testPred(3)
|
||||||
testPred(2)
|
testPred(2)
|
||||||
testPred(1)
|
testPred(1)
|
||||||
|
|
||||||
|
# bug #6526
|
||||||
|
type
|
||||||
|
BaseObj = ref object of RootObj
|
||||||
|
DerivedObj = ref object of BaseObj
|
||||||
|
|
||||||
|
proc `==`*[T1, T2: BaseObj](a: T1, b: T2): bool =
|
||||||
|
echo "baseobj =="
|
||||||
|
return true
|
||||||
|
|
||||||
|
let a = DerivedObj()
|
||||||
|
let b = DerivedObj()
|
||||||
|
echo a == b
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue