mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-30 04:07:55 +00:00
fix logic for dcEqIgnoreDistinct in sameType (#24197)
fixes #22523
There were 2 problems with the code in `sameType` for
`dcEqIgnoreDistinct`:
1. The code that skipped `{tyDistinct, tyGenericInst}` only ran if the
given types had different kinds. This is fixed by always performing this
skip.
2. The code block below that checks if `tyGenericInst`s have different
values still ran for `dcEqIgnoreDistinct` since it checks if the given
types are generic insts, not the skipped types (and also only the 1st
given type). This is fixed by only invoking this block for `dcEq`;
`dcEqOrDistinctOf` (which is unused) also skips the first given type.
Arguably there is another issue here that `skipGenericAlias` only ever
skips 1 type.
These combined fix the issue (`T` is `GenericInst(V, 1, distinct int)`
and `D[0]` is `GenericInst(D, 0, distinct int)`).
(cherry picked from commit b0e6d28782)
This commit is contained in:
@@ -1226,16 +1226,16 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
b = skipTypes(b[^1], {tyAlias})
|
||||
assert(a != nil)
|
||||
assert(b != nil)
|
||||
if a.kind != b.kind:
|
||||
case c.cmp
|
||||
of dcEq: return false
|
||||
of dcEqIgnoreDistinct:
|
||||
a = a.skipTypes({tyDistinct, tyGenericInst})
|
||||
b = b.skipTypes({tyDistinct, tyGenericInst})
|
||||
if a.kind != b.kind: return false
|
||||
of dcEqOrDistinctOf:
|
||||
a = a.skipTypes({tyDistinct, tyGenericInst})
|
||||
if a.kind != b.kind: return false
|
||||
case c.cmp
|
||||
of dcEq:
|
||||
if a.kind != b.kind: return false
|
||||
of dcEqIgnoreDistinct:
|
||||
a = a.skipTypes({tyDistinct, tyGenericInst})
|
||||
b = b.skipTypes({tyDistinct, tyGenericInst})
|
||||
if a.kind != b.kind: return false
|
||||
of dcEqOrDistinctOf:
|
||||
a = a.skipTypes({tyDistinct, tyGenericInst})
|
||||
if a.kind != b.kind: return false
|
||||
|
||||
#[
|
||||
The following code should not run in the case either side is an generic alias,
|
||||
@@ -1243,7 +1243,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
objects ie `type A[T] = SomeObject`
|
||||
]#
|
||||
# this is required by tunique_type but makes no sense really:
|
||||
if tyDistinct notin {x.kind, y.kind} and x.kind == tyGenericInst and IgnoreTupleFields notin c.flags:
|
||||
if c.cmp == dcEq and x.kind == tyGenericInst and
|
||||
IgnoreTupleFields notin c.flags and tyDistinct != y.kind:
|
||||
let
|
||||
lhs = x.skipGenericAlias
|
||||
rhs = y.skipGenericAlias
|
||||
|
||||
21
tests/distinct/tcomplexaddressableconv.nim
Normal file
21
tests/distinct/tcomplexaddressableconv.nim
Normal file
@@ -0,0 +1,21 @@
|
||||
# issue #22523
|
||||
|
||||
from std/typetraits import distinctBase
|
||||
|
||||
type
|
||||
V[p: static int] = distinct int
|
||||
D[p: static int] = distinct int
|
||||
T = V[1]
|
||||
|
||||
proc f(y: var T) = discard
|
||||
|
||||
var a: D[0]
|
||||
|
||||
static:
|
||||
doAssert distinctBase(T) is distinctBase(D[0])
|
||||
doAssert distinctBase(T) is int
|
||||
doAssert distinctBase(D[0]) is int
|
||||
doAssert T(a) is T
|
||||
|
||||
f(cast[ptr T](addr a)[])
|
||||
f(T(a))
|
||||
Reference in New Issue
Block a user