fix #1018
Previously, generic types originating from the same body symbol were compared structurally. The bug illustrates a case, where such a comparison is not correct. The new approach follows the established method used in typeRel.
This commit is contained in:
parent
8a0509b3b2
commit
b2aa70c6ef
1 changed files with 20 additions and 8 deletions
|
|
@ -830,6 +830,12 @@ proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
|
||||||
result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
|
result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
|
||||||
if not result: return
|
if not result: return
|
||||||
|
|
||||||
|
proc isGenericAlias*(t: PType): bool =
|
||||||
|
return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst
|
||||||
|
|
||||||
|
proc skipGenericAlias*(t: PType): PType =
|
||||||
|
return if t.isGenericAlias: t.lastSon else: t
|
||||||
|
|
||||||
proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
template cycleCheck() =
|
template cycleCheck() =
|
||||||
# believe it or not, the direct check for ``containsOrIncl(c, a, b)``
|
# believe it or not, the direct check for ``containsOrIncl(c, a, b)``
|
||||||
|
|
@ -860,6 +866,19 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
of dcEqOrDistinctOf:
|
of dcEqOrDistinctOf:
|
||||||
while a.kind == tyDistinct: a = a.sons[0]
|
while a.kind == tyDistinct: a = a.sons[0]
|
||||||
if a.kind != b.kind: return false
|
if a.kind != b.kind: return false
|
||||||
|
|
||||||
|
if x.kind == tyGenericInst:
|
||||||
|
let
|
||||||
|
lhs = x.skipGenericAlias
|
||||||
|
rhs = y.skipGenericAlias
|
||||||
|
if rhs.kind != tyGenericInst or lhs.base != rhs.base:
|
||||||
|
return false
|
||||||
|
for i in 1 .. lhs.len - 2:
|
||||||
|
let ff = rhs.sons[i]
|
||||||
|
let aa = lhs.sons[i]
|
||||||
|
if not sameTypeAux(ff, aa, c): return false
|
||||||
|
return true
|
||||||
|
|
||||||
case a.kind
|
case a.kind
|
||||||
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||||
tyInt..tyBigNum, tyStmt, tyExpr:
|
tyInt..tyBigNum, tyStmt, tyExpr:
|
||||||
|
|
@ -884,8 +903,6 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
cycleCheck()
|
cycleCheck()
|
||||||
result = sameTuple(a, b, c) and sameFlags(a, b)
|
result = sameTuple(a, b, c) and sameFlags(a, b)
|
||||||
of tyGenericInst:
|
|
||||||
result = sameTypeAux(lastSon(a), lastSon(b), c)
|
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
if c.cmp == dcEqIgnoreDistinct: result = false
|
if c.cmp == dcEqIgnoreDistinct: result = false
|
||||||
elif ExactTypeDescValues in c.flags:
|
elif ExactTypeDescValues in c.flags:
|
||||||
|
|
@ -912,6 +929,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
|
result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
|
||||||
sameValue(a.n.sons[0], b.n.sons[0]) and
|
sameValue(a.n.sons[0], b.n.sons[0]) and
|
||||||
sameValue(a.n.sons[1], b.n.sons[1])
|
sameValue(a.n.sons[1], b.n.sons[1])
|
||||||
|
of tyGenericInst: discard
|
||||||
of tyNone: result = false
|
of tyNone: result = false
|
||||||
|
|
||||||
proc sameBackendType*(x, y: PType): bool =
|
proc sameBackendType*(x, y: PType): bool =
|
||||||
|
|
@ -1005,12 +1023,6 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||||
a = a.sons[i]
|
a = a.sons[i]
|
||||||
result = a.kind == last
|
result = a.kind == last
|
||||||
|
|
||||||
proc isGenericAlias*(t: PType): bool =
|
|
||||||
return t.kind == tyGenericInst and t.lastSon.kind == tyGenericInst
|
|
||||||
|
|
||||||
proc skipGenericAlias*(t: PType): PType =
|
|
||||||
return if t.isGenericAlias: t.lastSon else: t
|
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
||||||
flags: TTypeAllowedFlags = {}): bool =
|
flags: TTypeAllowedFlags = {}): bool =
|
||||||
assert(kind in {skVar, skLet, skConst, skParam, skResult})
|
assert(kind in {skVar, skLet, skConst, skParam, skResult})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue