fixes #22936; Generic inheritance matching gives type mismatch when object has members

This commit is contained in:
ringabout
2026-05-22 22:20:18 +08:00
parent 9f5c193c1d
commit 09bf39bed8
2 changed files with 41 additions and 0 deletions

View File

@@ -1754,6 +1754,19 @@ 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:
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)

View File

@@ -5,3 +5,31 @@ type
proc newFoo[T](): Foo[T] = Foo[T](newSeq[T]())
var x = newFoo[Bar[int]]()
# issue #22936
import std/macros
type
InternalFutureBase = object of RootObj
FutureBase = ref object of InternalFutureBase
Future[T] = ref object of FutureBase
internalValue: T
B[T, E] = ref object of Future[T]
proc take[F: Future](fut: F) = discard
proc takeMany[F: Future](futs: seq[F]) = discard
macro checkFutures[F: Future](futs: seq[F]): untyped =
newEmptyNode()
var future: B[void, void]
var futures: seq[B[void, void]]
take(future)
takeMany(futures)
checkFutures(futures)