From f29239381672f260ddae78974c7e29e8a7a8a815 Mon Sep 17 00:00:00 2001 From: metagn Date: Fri, 8 Nov 2024 10:36:52 +0300 Subject: [PATCH] skip tyAlias in generic alias checks [backport:2.0] (#24417) fixes #24415 Since #23978 (which is in 2.0), all generic types that alias to another type now insert a `tyAlias` layer in their value. However the `skipGenericAlias` etc code which `sigmatch` uses is not updated for this, so `tyAlias` is now skipped in these. The relevant code in sigmatch is: https://github.com/nim-lang/Nim/blob/67ad1ae1598b08039c971812dc172dd48624b7b0/compiler/sigmatch.nim#L1668-L1673 This behavior is also suspicious IMO, not skipping a structural `tyGenericInst` alias can be useful for code like #10220, but this is currently arbitrarily decided based on "depth" and whether the alias is to another `tyGenericInst` type or not. Maybe in the future we could enforce the use of a nominal type. (cherry picked from commit 45b8434c7d1a734c84a1e160cf833fe55c44528c) --- compiler/types.nim | 10 ++++++---- tests/overload/tgenericalias.nim | 9 +++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/types.nim b/compiler/types.nim index a6694ab26a..bc6de5098b 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1201,17 +1201,19 @@ proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool = if not result: return proc isGenericAlias*(t: PType): bool = - return t.kind == tyGenericInst and t.skipModifier.kind == tyGenericInst + return t.kind == tyGenericInst and t.skipModifier.skipTypes({tyAlias}).kind == tyGenericInst proc genericAliasDepth*(t: PType): int = result = 0 - var it = t + var it = t.skipTypes({tyAlias}) while it.isGenericAlias: - it = it.skipModifier + it = it.skipModifier.skipTypes({tyAlias}) inc result proc skipGenericAlias*(t: PType): PType = - return if t.isGenericAlias: t.skipModifier else: t + result = t.skipTypes({tyAlias}) + if result.isGenericAlias: + result = result.skipModifier.skipTypes({tyAlias}) proc sameFlags*(a, b: PType): bool {.inline.} = result = eqTypeFlags*a.flags == eqTypeFlags*b.flags diff --git a/tests/overload/tgenericalias.nim b/tests/overload/tgenericalias.nim index 50a44bd324..cb3e8985db 100644 --- a/tests/overload/tgenericalias.nim +++ b/tests/overload/tgenericalias.nim @@ -11,3 +11,12 @@ block: # issue #13799 proc works2(): Y[int] = t(X[int, int]) proc works3(): Y[int] = t(Y[int]) proc broken(): Y[int] = s(Y[int]) + +block: # issue #24415 + type GVec2[T] = object + x, y: T + type Uniform[T] = T + proc foo(v: Uniform[GVec2[float32]]): float32 = + result = v.x + let f = GVec2[float32](x: 1.0f, y: 2.0f) + doAssert foo(f) == 1.0f