From 2ddeabceaf343e59ea24f052cb7df04f1e66547f Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Fri, 6 Feb 2026 00:54:04 +0100 Subject: [PATCH] Fixes #25340 (#25389) (cherry picked from commit 296b2789b52079d55f9f472336d122b197fa9f20) --- compiler/semtypes.nim | 2 +- compiler/sigmatch.nim | 50 ++++++++++++++++++++-------------------- tests/typerel/t25340.nim | 16 +++++++++++++ 3 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 tests/typerel/t25340.nim diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index add770e6d4..22d70fa64e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -986,7 +986,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} = proc tryAddInheritedFields(c: PContext, check: var IntSet, pos: var int, obj: PType, n: PNode, isPartial = false, innerObj: PType = nil): bool = if ((not isPartial) and (obj.kind notin {tyObject, tyGenericParam} or tfFinal in obj.flags)) or - (innerObj != nil and obj.sym.id == innerObj.sym.id): + (innerObj != nil and obj.id == innerObj.id): localError(c.config, n.info, "Cannot inherit from: '" & $obj & "'") result = false elif obj.kind == tyObject: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 4ea4fe7c65..e213289bcb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1679,7 +1679,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, elif a.kind == tyGenericInst: if roota.base == rootf.base: let nextFlags = flags + {trNoCovariance} - var hasCovariance = false # YYYY result = isEqual @@ -1691,7 +1690,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if res notin {isEqual, isGeneric}: if trNoCovariance notin flags and ff.kind == aa.kind: let paramFlags = rootf.base[i-1].flags - hasCovariance = + let hasCovariance = if tfCovariant in paramFlags: if tfWeakCovariant in paramFlags: isCovariantPtr(c, ff, aa) @@ -1702,35 +1701,36 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, typeRel(c, aa, ff, flags) == isSubtype if hasCovariance: continue + result = isNone + break - return isNone - if prev == nil: put(c, f, a) - else: - let fKind = rootf.last.kind - if fKind in {tyAnd, tyOr}: - result = typeRel(c, last(f), a, flags) - if result != isNone: put(c, f, a) + if result != isNone: + if prev == nil: put(c, f, a) return - var aAsObject = roota.last + let fKind = rootf.last.kind + if fKind in {tyAnd, tyOr}: + result = typeRel(c, last(f), a, flags) + if result != isNone: put(c, f, a) + return - if fKind in {tyRef, tyPtr}: - if aAsObject.kind == tyObject: - # bug #7600, tyObject cannot be passed - # as argument to tyRef/tyPtr - return isNone - elif aAsObject.kind == fKind: - aAsObject = aAsObject.base + var aAsObject = roota.last - if aAsObject.kind == tyObject and trIsOutParam notin flags: - let baseType = aAsObject.base - if baseType != nil: - 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 + if fKind in {tyRef, tyPtr}: + if aAsObject.kind == tyObject: + # bug #7600, tyObject cannot be passed + # as argument to tyRef/tyPtr + return isNone + elif aAsObject.kind == fKind: + aAsObject = aAsObject.base - result = isNone + if aAsObject.kind == tyObject and trIsOutParam notin flags: + let baseType = aAsObject.base + if baseType != nil: + 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 else: assert last(origF) != nil result = typeRel(c, last(origF), a, flags) diff --git a/tests/typerel/t25340.nim b/tests/typerel/t25340.nim new file mode 100644 index 0000000000..2ddcd4cbce --- /dev/null +++ b/tests/typerel/t25340.nim @@ -0,0 +1,16 @@ + +type + Foo[T] = object of T + +template inheritanceCheck(a, b: untyped) = + doAssert a is b + doAssert b isnot a + +inheritanceCheck Foo[RootObj], RootObj + +inheritanceCheck Foo[Foo[RootObj]], RootObj +inheritanceCheck Foo[Foo[RootObj]], Foo[RootObj] + +inheritanceCheck Foo[Foo[Foo[RootObj]]], RootObj +inheritanceCheck Foo[Foo[Foo[RootObj]]], Foo[RootObj] +inheritanceCheck Foo[Foo[Foo[RootObj]]], Foo[Foo[RootObj]]