Skip to content

Commit fb93295

Browse files
metagnAraq
andauthored
fix compound inheritance penalty (#24775)
fixes #24773 `c.inheritancePenalty` is supposed to be used for the entire match, but in these places the inheritance penalty of a single argument overrides the entire match penalty. The `+ ord(c.inheritancePenalty < 0)` is copied from other places that use the same idiom, the intent is that the existing penalty changes from -1 to 0 first to mark that it participates in inheritance before adding the inheritance depth. --------- Co-authored-by: Andreas Rumpf <araq4k@proton.me>
1 parent 9ebfa79 commit fb93295

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

compiler/sigmatch.nim

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,12 +1541,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
15411541
reduceToBase(a)
15421542
if effectiveArgType.kind == tyObject:
15431543
if sameObjectTypes(f, effectiveArgType):
1544-
c.inheritancePenalty = if tfFinal in f.flags: -1 else: 0
1544+
if tfFinal notin f.flags:
1545+
inc c.inheritancePenalty, ord(c.inheritancePenalty < 0)
15451546
result = isEqual
15461547
# elif tfHasMeta in f.flags: result = recordRel(c, f, a)
15471548
elif trIsOutParam notin flags:
1548-
c.inheritancePenalty = isObjectSubtype(c, effectiveArgType, f, nil)
1549-
if c.inheritancePenalty > 0:
1549+
let depth = isObjectSubtype(c, effectiveArgType, f, nil)
1550+
if depth > 0:
1551+
inc c.inheritancePenalty, depth + ord(c.inheritancePenalty < 0)
15501552
result = isSubtype
15511553
of tyDistinct:
15521554
a = a.skipTypes({tyOwned, tyGenericInst, tyRange})
@@ -1846,9 +1848,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
18461848
if c.inheritancePenalty > -1:
18471849
minInheritance = min(minInheritance, c.inheritancePenalty)
18481850
result = x
1851+
c.inheritancePenalty = oldInheritancePenalty
18491852
if result >= isIntConv:
18501853
if minInheritance < maxInheritancePenalty:
1851-
c.inheritancePenalty = oldInheritancePenalty + minInheritance
1854+
inc c.inheritancePenalty, minInheritance + ord(c.inheritancePenalty < 0)
18521855
if result > isGeneric: result = isGeneric
18531856
bindingRet result
18541857
else:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# issue #24773
2+
3+
import std/assertions
4+
5+
type
6+
A {.inheritable.} = object
7+
B = object of A
8+
C = object of B
9+
10+
proc add1(v: B) =
11+
doAssert true
12+
13+
proc add1(v: A) =
14+
doAssert false
15+
16+
proc add2(v: B, v2: A) =
17+
doAssert true
18+
19+
proc add2(v: A, v2: A) =
20+
doAssert false
21+
22+
var x: C
23+
var y: B
24+
25+
add1(x)
26+
add2(x, y)

0 commit comments

Comments
 (0)