From 5a90fe012b72eb1485ca7ccefa1e817054acf764 Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Wed, 17 Sep 2025 11:50:49 -0400 Subject: [PATCH 1/4] fix temp --- compiler/sigmatch.nim | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index d3d99a355aa80..01ace6a72fc70 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1891,6 +1891,21 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, return isNone if doBind: put(c, f, a) return isGeneric + elif effectiveArgType.kind == tyOr: + let oldInheritancePenalty = c.inheritancePenalty + var + bestPenatly = maxInheritancePenalty + bestMatch = isNone + for kid in effectiveArgType.kids: + let x = typeRel(c, f, kid, flags) + if x > bestMatch: + bestMatch = x + bestPenatly = c.inheritancePenalty + c.inheritancePenalty = oldInheritancePenalty + c.inheritancePenalty = oldInheritancePenalty + if bestMatch > isNone: + c.inheritancePenalty = bestPenatly + result = bestMatch else: return isNone of tyUserTypeClassInst, tyUserTypeClass: From 8644fca5295456799a53cb16435eb87998ea107a Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Wed, 17 Sep 2025 11:59:53 -0400 Subject: [PATCH 2/4] add test --- tests/typerel/tsigmatch.nim | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/typerel/tsigmatch.nim b/tests/typerel/tsigmatch.nim index 7541f2028d444..c92c1cc339649 100644 --- a/tests/typerel/tsigmatch.nim +++ b/tests/typerel/tsigmatch.nim @@ -4,3 +4,16 @@ block: # bug #13618 doAssert test(^1) == 1 doAssert test(1) == 1 + +block: # #25174 + type Foo = object + type Bar = object + type Quz = object + + proc bar[T: Foo | Bar](x: T): string = + return $typeof(T) + proc bar[T: object](x: T): string = + return $typeof(T) + doAssert bar(Foo()) == "Foo" + doAssert bar(Bar()) == "Bar" + doAssert bar(Quz()) == "Quz" From bc88a53ba3927c296959fdb323c64cbc594535d2 Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Wed, 17 Sep 2025 15:49:28 -0400 Subject: [PATCH 3/4] simplify --- compiler/sigmatch.nim | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 01ace6a72fc70..2eed7b55887a4 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1892,20 +1892,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if doBind: put(c, f, a) return isGeneric elif effectiveArgType.kind == tyOr: - let oldInheritancePenalty = c.inheritancePenalty - var - bestPenatly = maxInheritancePenalty - bestMatch = isNone for kid in effectiveArgType.kids: - let x = typeRel(c, f, kid, flags) - if x > bestMatch: - bestMatch = x - bestPenatly = c.inheritancePenalty - c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty = oldInheritancePenalty - if bestMatch > isNone: - c.inheritancePenalty = bestPenatly - result = bestMatch + if typeRel(c, f, kid, flags) >= isSubtype: + result = isGeneric + #if doBind: put(c, f, kid) + break else: return isNone of tyUserTypeClassInst, tyUserTypeClass: From bbeeb4ebf7fbb353d6398b8e00f6d7f96b4adba9 Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Sat, 20 Sep 2025 14:00:15 -0400 Subject: [PATCH 4/4] adjust generic inv --- compiler/sigmatch.nim | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 2eed7b55887a4..21697f33d3438 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1742,7 +1742,17 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if ff != nil: result = typeRel(c, ff, a, flags) of tyGenericInvocation: - var x = a.skipGenericAlias + var x = a + while x != nil: + if x.kind == tyAlias: + x = x.last + elif x.isGenericAlias: + if f[0] == x[0]: + break + else: + x = x.last + else: + break if x.kind == tyGenericParam and x.len > 0: x = x.last let concpt = f.reduceToBase @@ -1751,7 +1761,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, preventHack = true x = x.last # XXX: This is very hacky. It should be moved back into liftTypeParam - if x.kind in {tyGenericInst, tyArray} and + if x.kind in {tyArray} and c.calleeSym != nil and c.calleeSym.kind in {skProc, skFunc} and c.call != nil and not preventHack: let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f) @@ -1807,10 +1817,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, else: let key = f[i] let old = lookup(c.bindings, key) - if old == nil: + if typeRel(c, key, x, flags) == isNone: + result = isNone + elif old == nil or typeRel(c, old, x, flags + {trDontBind}) > isNone: put(c, key, x) - elif typeRel(c, old, x, flags + {trDontBind}) == isNone: - return isNone + else: + result = isNone var depth = -1 if fobj != nil and aobj != nil and askip == fskip: depth = isObjectSubtype(c, aobj, fobj, f) @@ -1895,7 +1907,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, for kid in effectiveArgType.kids: if typeRel(c, f, kid, flags) >= isSubtype: result = isGeneric - #if doBind: put(c, f, kid) break else: return isNone