Skip to content

Commit

Permalink
skip tyAlias in generic alias checks [backport:2.0] (#24417)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
metagn authored Nov 8, 2024
1 parent 67ad1ae commit 45b8434
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
10 changes: 6 additions & 4 deletions compiler/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions tests/overload/tgenericalias.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 45b8434

Please sign in to comment.