This commit is contained in:
Araq 2017-10-27 20:55:36 +02:00
commit 9c00f6decd
3 changed files with 36 additions and 15 deletions

View file

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

View file

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

View file

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