diff options
author | metagn <metagngn@gmail.com> | 2024-09-29 11:23:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-29 10:23:59 +0200 |
commit | b0e6d28782ce8c3d8e0b4a64e01f21d6f900648f (patch) | |
tree | acc9c48b9b42049f4eba5d8eff1961943f2b8895 /compiler | |
parent | 7974a2208c848440cc5188ee3f38f0432b2ee1db (diff) | |
download | Nim-b0e6d28782ce8c3d8e0b4a64e01f21d6f900648f.tar.gz |
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)`). #24037 shouldn't be a dependency but the diff follows it.
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/types.nim | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/compiler/types.nim b/compiler/types.nim index ec310e248..a441b0ea2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1250,18 +1250,18 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = b = skipTypes(b.last, aliasSkipSet) assert(a != nil) assert(b != nil) - if a.kind != b.kind: - case c.cmp - of dcEq: return false - of dcEqIgnoreDistinct: - let distinctSkipSet = maybeSkipRange({tyDistinct, tyGenericInst}) - a = a.skipTypes(distinctSkipSet) - b = b.skipTypes(distinctSkipSet) - if a.kind != b.kind: return false - of dcEqOrDistinctOf: - let distinctSkipSet = maybeSkipRange({tyDistinct, tyGenericInst}) - a = a.skipTypes(distinctSkipSet) - if a.kind != b.kind: return false + case c.cmp + of dcEq: + if a.kind != b.kind: return false + of dcEqIgnoreDistinct: + let distinctSkipSet = maybeSkipRange({tyDistinct, tyGenericInst}) + a = a.skipTypes(distinctSkipSet) + b = b.skipTypes(distinctSkipSet) + if a.kind != b.kind: return false + of dcEqOrDistinctOf: + let distinctSkipSet = maybeSkipRange({tyDistinct, tyGenericInst}) + a = a.skipTypes(distinctSkipSet) + if a.kind != b.kind: return false #[ The following code should not run in the case either side is an generic alias, @@ -1269,7 +1269,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 x.kind == tyGenericInst and IgnoreTupleFields notin c.flags and tyDistinct != y.kind: + if c.cmp == dcEq and x.kind == tyGenericInst and + IgnoreTupleFields notin c.flags and tyDistinct != y.kind: let lhs = x.skipGenericAlias rhs = y.skipGenericAlias |