From ebeef1067f5aaf8ea6ec9c63c513e861e33dcde6 Mon Sep 17 00:00:00 2001 From: metagn Date: Thu, 20 Feb 2025 01:01:26 +0300 Subject: [PATCH] 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. --- compiler/sigmatch.nim | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 950ebe5196..b175549dcb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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..= 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