mirror of
https://github.com/golang/go
synced 2024-11-19 17:24:41 -07:00
cmd/compile: simplify Eqtype
Change-Id: I443f997ed53f965ef5b33734351ab8a07a09746b Reviewed-on: https://go-review.googlesource.com/20213 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
132ebeac3f
commit
62e26e7511
@ -705,32 +705,22 @@ func eqnote(a, b *string) bool {
|
|||||||
return a == b || a != nil && b != nil && *a == *b
|
return a == b || a != nil && b != nil && *a == *b
|
||||||
}
|
}
|
||||||
|
|
||||||
type TypePairList struct {
|
// Eqtype reports whether t1 and t2 are identical, following the spec rules.
|
||||||
t1 *Type
|
|
||||||
t2 *Type
|
|
||||||
next *TypePairList
|
|
||||||
}
|
|
||||||
|
|
||||||
func onlist(l *TypePairList, t1 *Type, t2 *Type) bool {
|
|
||||||
for ; l != nil; l = l.next {
|
|
||||||
if (l.t1 == t1 && l.t2 == t2) || (l.t1 == t2 && l.t2 == t1) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return 1 if t1 and t2 are identical, following the spec rules.
|
|
||||||
//
|
//
|
||||||
// Any cyclic type must go through a named type, and if one is
|
// Any cyclic type must go through a named type, and if one is
|
||||||
// named, it is only identical to the other if they are the same
|
// named, it is only identical to the other if they are the same
|
||||||
// pointer (t1 == t2), so there's no chance of chasing cycles
|
// pointer (t1 == t2), so there's no chance of chasing cycles
|
||||||
// ad infinitum, so no need for a depth counter.
|
// ad infinitum, so no need for a depth counter.
|
||||||
func Eqtype(t1 *Type, t2 *Type) bool {
|
func Eqtype(t1, t2 *Type) bool {
|
||||||
return eqtype1(t1, t2, nil)
|
return eqtype1(t1, t2, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
type typePair struct {
|
||||||
|
t1 *Type
|
||||||
|
t2 *Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool {
|
||||||
if t1 == t2 {
|
if t1 == t2 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -738,30 +728,24 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if t1.Sym != nil || t2.Sym != nil {
|
if t1.Sym != nil || t2.Sym != nil {
|
||||||
// Special case: we keep byte and uint8 separate
|
// Special case: we keep byte/uint8 and rune/int32
|
||||||
// for error messages. Treat them as equal.
|
// separate for error messages. Treat them as equal.
|
||||||
switch t1.Etype {
|
switch t1.Etype {
|
||||||
case TUINT8:
|
case TUINT8:
|
||||||
if (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) {
|
return (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype)
|
||||||
return true
|
case TINT32:
|
||||||
}
|
return (t1 == Types[TINT32] || t1 == runetype) && (t2 == Types[TINT32] || t2 == runetype)
|
||||||
|
default:
|
||||||
case TINT, TINT32:
|
|
||||||
if (t1 == Types[runetype.Etype] || t1 == runetype) && (t2 == Types[runetype.Etype] || t2 == runetype) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if onlist(assumed_equal, t1, t2) {
|
if assumedEqual == nil {
|
||||||
|
assumedEqual = make(map[typePair]struct{})
|
||||||
|
} else if _, ok := assumedEqual[typePair{t1, t2}]; ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
var l TypePairList
|
assumedEqual[typePair{t1, t2}] = struct{}{}
|
||||||
l.next = assumed_equal
|
|
||||||
l.t1 = t1
|
|
||||||
l.t2 = t2
|
|
||||||
|
|
||||||
switch t1.Etype {
|
switch t1.Etype {
|
||||||
case TINTER, TSTRUCT:
|
case TINTER, TSTRUCT:
|
||||||
@ -771,7 +755,7 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
|||||||
if t1.Etype != TFIELD || t2.Etype != TFIELD {
|
if t1.Etype != TFIELD || t2.Etype != TFIELD {
|
||||||
Fatalf("struct/interface missing field: %v %v", t1, t2)
|
Fatalf("struct/interface missing field: %v %v", t1, t2)
|
||||||
}
|
}
|
||||||
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) {
|
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, assumedEqual) || !eqnote(t1.Note, t2.Note) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,7 +781,7 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
|||||||
if ta.Etype != TFIELD || tb.Etype != TFIELD {
|
if ta.Etype != TFIELD || tb.Etype != TFIELD {
|
||||||
Fatalf("func struct missing field: %v %v", ta, tb)
|
Fatalf("func struct missing field: %v %v", ta, tb)
|
||||||
}
|
}
|
||||||
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) {
|
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, assumedEqual) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -823,10 +807,7 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) {
|
return eqtype1(t1.Down, t2.Down, assumedEqual) && eqtype1(t1.Type, t2.Type, assumedEqual)
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are t1 and t2 equal struct types when field names are ignored?
|
// Are t1 and t2 equal struct types when field names are ignored?
|
||||||
|
Loading…
Reference in New Issue
Block a user