mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-24 08:15:25 +00:00
remove structural equality check for objects and distinct types (#24448)
follows up #24425, fixes #18861, fixes #22445 Since #24425 generic object and distinct types now accurately link back to their generic instantiations. To work around this issue previously, type matching checked if generic objects/distinct types were *structurally* equal, which caused false positives with types that didn't use generic parameters in their structures. This structural check is now removed, in cases where generic objects/distinct types require a nontrivial equality check, the generic parameters of the `typeInst` fields are checked for equality instead. The check is copied from `tyGenericInst`, but the check in `tyGenericInst` is not always sufficient as this type can be skipped or unreachable in the case of `ref object`s.
This commit is contained in:
@@ -1306,26 +1306,34 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
cycleCheck()
|
||||
result = sameTypeAux(a.skipModifier, b.skipModifier, c)
|
||||
of tyObject:
|
||||
withoutShallowFlags:
|
||||
result = sameFlags(a, b)
|
||||
if result:
|
||||
ifFastObjectTypeCheckFailed(a, b):
|
||||
cycleCheck()
|
||||
if a.typeInst != nil and b.typeInst != nil:
|
||||
# this is required because of `ref object`s,
|
||||
# the value of their dereferences are not wrapped in `tyGenericInst`,
|
||||
# so we need to check the generic parameters here
|
||||
for ff, aa in underspecifiedPairs(a.typeInst, b.typeInst, 1, -1):
|
||||
if not sameTypeAux(ff, aa, c): return false
|
||||
# XXX should be removed in favor of above lines,
|
||||
# structural equality is wrong in general:
|
||||
result = sameObjectStructures(a, b, c) and sameFlags(a, b)
|
||||
# should be generic, and belong to the same generic head type:
|
||||
assert a.typeInst != nil, "generic object " & $a & " has no typeInst"
|
||||
assert b.typeInst != nil, "generic object " & $b & " has no typeInst"
|
||||
if result:
|
||||
withoutShallowFlags:
|
||||
# this is required because of generic `ref object`s,
|
||||
# the value of their dereferences are not wrapped in `tyGenericInst`,
|
||||
# so we need to check the generic parameters here
|
||||
for ff, aa in underspecifiedPairs(a.typeInst, b.typeInst, 1, -1):
|
||||
if not sameTypeAux(ff, aa, c): return false
|
||||
of tyDistinct:
|
||||
cycleCheck()
|
||||
if c.cmp == dcEq:
|
||||
if sameFlags(a, b):
|
||||
result = sameFlags(a, b)
|
||||
if result:
|
||||
ifFastObjectTypeCheckFailed(a, b):
|
||||
# XXX should be removed in favor of checking generic params,
|
||||
# structural equality is wrong in general:
|
||||
result = sameTypeAux(a.elementType, b.elementType, c)
|
||||
# should be generic, and belong to the same generic head type:
|
||||
assert a.typeInst != nil, "generic distinct type " & $a & " has no typeInst"
|
||||
assert b.typeInst != nil, "generic distinct type " & $b & " has no typeInst"
|
||||
withoutShallowFlags:
|
||||
# just in case `tyGenericInst` was skipped at some point,
|
||||
# we need to check the generic parameters here
|
||||
for ff, aa in underspecifiedPairs(a.typeInst, b.typeInst, 1, -1):
|
||||
if not sameTypeAux(ff, aa, c): return false
|
||||
else:
|
||||
result = sameTypeAux(a.elementType, b.elementType, c) and sameFlags(a, b)
|
||||
of tyEnum, tyForward:
|
||||
|
||||
Reference in New Issue
Block a user