fix: improve generic subtype handling in typeRel function

This commit is contained in:
ringabout
2026-05-22 23:41:21 +08:00
parent 09bf39bed8
commit 497e1e04bb

View File

@@ -1754,22 +1754,21 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
considerPreviousT:
if a == f or a.kind == tyGenericInst and a.skipGenericAlias[0] == f:
bindingRet isGeneric
var depth = -1
# Generic constraints like `F: Future` reach sigmatch as a `tyGenericBody`.
# Accept descendants of the generic family here as well, not just direct
# `Future[...]` instantiations.
if isGenericSubtype(c, a, f, depth, f):
if depth > 0:
let ff = last(f)
if ff != nil:
result = typeRel(c, ff, a, flags)
if result == isNone and a.kind == tyGenericInst:
var depth = -1
# Generic constraints like `F: Future` can miss in `last(f)` when the
# actual type inherits from a concrete generic instantiation.
if isGenericSubtype(c, a, f, depth, f) and depth > 0:
var askip = skippedNone
let aobj = a.skipToObject(askip)
if aobj != nil and tfFinal notin aobj.flags:
# Keep overload ranking consistent with other inheritance-based
# matches: deeper descendants are slightly worse candidates.
inc c.inheritancePenalty, depth + int(c.inheritancePenalty < 0)
bindingRet(if depth == 0: isGeneric else: isSubtype)
let ff = last(f)
if ff != nil:
result = typeRel(c, ff, a, flags)
result = isGeneric
of tyGenericInvocation:
var x = a.skipGenericAlias
if x.kind == tyGenericParam and x.len > 0: