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:
67ad1ae159/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 45b8434c7d)
This commit is contained in:
metagn
2024-11-08 10:36:52 +03:00
committed by narimiran
parent 6ec663f7bc
commit f292393816
2 changed files with 15 additions and 4 deletions

View File

@@ -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

View File

@@ -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