adapt generic matches to inheritance penalty of final objects (#24691)

Applies #24144 to the equivalent matches of generic types, and adds the
behavior to matches of generic invocations to generic invocations. Not
encountered in many cases so it's hard to come up with tests but an
example is the test code in #24688, the match to the generic body never
sets the inheritance penalty leaving it at -1, but the match to the
generic invocation sets it to 0 which matches worse, when it should set
it to -1 because the object does not participate in inheritance.
This commit is contained in:
metagn
2025-02-20 01:01:26 +03:00
committed by GitHub
parent 510ac84518
commit ebeef1067f

View File

@@ -1692,7 +1692,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
if aAsObject.kind == tyObject and trIsOutParam notin flags:
let baseType = aAsObject.base
if baseType != nil:
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
if tfFinal notin aAsObject.flags:
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
let ret = typeRel(c, f, baseType, flags)
return if ret in {isEqual,isGeneric}: isSubtype else: ret
@@ -1733,6 +1734,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let tr = typeRel(c, f[i], x[i], flags)
if tr <= isSubtype: return
result = isGeneric
let impl = last(f[0])
if impl.kind == tyObject and tfFinal notin impl.flags:
# match non-invocation case
inc c.inheritancePenalty, 0 + int(c.inheritancePenalty < 0)
elif x.kind == tyGenericInst and f[0] == x[0] and
x.len - 1 == f.len:
for i in 1..<f.len:
@@ -1789,7 +1794,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
depth = -1
if depth >= 0:
inc c.inheritancePenalty, depth + int(c.inheritancePenalty < 0)
if aobj.kind == tyObject and tfFinal notin aobj.flags:
inc c.inheritancePenalty, depth + int(c.inheritancePenalty < 0)
# bug #4863: We still need to bind generic alias crap, so
# we cannot return immediately:
result = if depth == 0: isGeneric else: isSubtype