Skip to content

Commit

Permalink
cmd/compile: extract gc.eqtype as types.Identical
Browse files Browse the repository at this point in the history
For symmetry with go/types.Identical.

Passes toolstash-check.

Change-Id: Id19c3956e44ed8e2d9f203d15824322cc5842d3d
Reviewed-on: https://go-review.googlesource.com/c/143180
Run-TryBot: Matthew Dempsky <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Robert Griesemer <[email protected]>
  • Loading branch information
mdempsky committed Oct 18, 2018
1 parent a440cc0 commit 2d58fba
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 155 deletions.
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/closure.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ func walkclosure(clo *Node, init *Nodes) *Node {

// non-escaping temp to use, if any.
if x := prealloc[clo]; x != nil {
if !eqtype(typ, x.Type) {
if !types.Identical(typ, x.Type) {
panic("closure type does not match order's assigned type")
}
clos.Left.Right = x
Expand Down Expand Up @@ -530,7 +530,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {

// non-escaping temp to use, if any.
if x := prealloc[n]; x != nil {
if !eqtype(typ, x.Type) {
if !types.Identical(typ, x.Type) {
panic("partial call type does not match order's assigned type")
}
clos.Left.Right = x
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
}

// avoid repeated calculations, errors
if eqtype(n.Type, t) {
if types.Identical(n.Type, t) {
return n
}

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/dcl.go
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F
}
// eqtype only checks that incoming and result parameters match,
// so explicitly check that the receiver parameters match too.
if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
}
return f
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/esc.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ opSwitch:
// it is also a dereference, because it is implicitly
// dereferenced (see #12588)
if n.Type.IsArray() &&
!(n.Right.Type.IsPtr() && eqtype(n.Right.Type.Elem(), n.Type)) {
!(n.Right.Type.IsPtr() && types.Identical(n.Right.Type.Elem(), n.Type)) {
e.escassignWhyWhere(n.List.Second(), n.Right, "range", n)
} else {
e.escassignDereference(n.List.Second(), n.Right, e.stepAssignWhere(n.List.Second(), n.Right, "range-deref", n))
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
n := importsym(ipkg, s, op)
if n.Op != ONONAME {
if n.Op == op && (n.Class() != ctxt || !eqtype(n.Type, t)) {
if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
key := t.LongString()
a := o.free[key]
for i, n := range a {
if eqtype(t, n.Type) {
if types.Identical(t, n.Type) {
v = a[i]
a[i] = a[len(a)-1]
a = a[:len(a)-1]
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ func methods(t *types.Type) []*Sig {

if !sig.isym.Siggen() {
sig.isym.SetSiggen(true)
if !eqtype(this, it) {
if !types.Identical(this, it) {
compiling_wrappers = true
genwrapper(it, f, sig.isym)
compiling_wrappers = false
Expand All @@ -414,7 +414,7 @@ func methods(t *types.Type) []*Sig {

if !sig.tsym.Siggen() {
sig.tsym.SetSiggen(true)
if !eqtype(this, t) {
if !types.Identical(this, t) {
compiling_wrappers = true
genwrapper(t, f, sig.tsym)
compiling_wrappers = false
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/compile/internal/gc/sinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
orig := r
r = r.Name.Defn.Right

for r.Op == OCONVNOP && !eqtype(r.Type, l.Type) {
for r.Op == OCONVNOP && !types.Identical(r.Type, l.Type) {
r = r.Left
}

Expand Down Expand Up @@ -833,7 +833,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
var a *Node
if x := prealloc[n]; x != nil {
// temp allocated during order.go for dddarg
if !eqtype(t, x.Type) {
if !types.Identical(t, x.Type) {
panic("dotdotdot base type does not match order's assigned type")
}

Expand Down Expand Up @@ -1154,7 +1154,7 @@ func oaslit(n *Node, init *Nodes) bool {
// not a special composite literal assignment
return false
}
if !eqtype(n.Left.Type, n.Right.Type) {
if !types.Identical(n.Left.Type, n.Right.Type) {
// not a special composite literal assignment
return false
}
Expand Down
131 changes: 9 additions & 122 deletions src/cmd/compile/internal/gc/subr.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,119 +529,6 @@ func methtype(t *types.Type) *types.Type {
return nil
}

// eqtype reports whether t1 and t2 are identical, following the spec rules.
//
// 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
// pointer (t1 == t2), so there's no chance of chasing cycles
// ad infinitum, so no need for a depth counter.
func eqtype(t1, t2 *types.Type) bool {
return eqtype1(t1, t2, true, nil)
}

// eqtypeIgnoreTags is like eqtype but it ignores struct tags for struct identity.
func eqtypeIgnoreTags(t1, t2 *types.Type) bool {
return eqtype1(t1, t2, false, nil)
}

type typePair struct {
t1 *types.Type
t2 *types.Type
}

func eqtype1(t1, t2 *types.Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool {
if t1 == t2 {
return true
}
if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke() || t2.Broke() {
return false
}
if t1.Sym != nil || t2.Sym != nil {
// Special case: we keep byte/uint8 and rune/int32
// separate for error messages. Treat them as equal.
switch t1.Etype {
case TUINT8:
return (t1 == types.Types[TUINT8] || t1 == types.Bytetype) && (t2 == types.Types[TUINT8] || t2 == types.Bytetype)
case TINT32:
return (t1 == types.Types[TINT32] || t1 == types.Runetype) && (t2 == types.Types[TINT32] || t2 == types.Runetype)
default:
return false
}
}

if assumedEqual == nil {
assumedEqual = make(map[typePair]struct{})
} else if _, ok := assumedEqual[typePair{t1, t2}]; ok {
return true
}
assumedEqual[typePair{t1, t2}] = struct{}{}

switch t1.Etype {
case TINTER:
if t1.NumFields() != t2.NumFields() {
return false
}
for i, f1 := range t1.FieldSlice() {
f2 := t2.Field(i)
if f1.Sym != f2.Sym || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
return false
}
}
return true

case TSTRUCT:
if t1.NumFields() != t2.NumFields() {
return false
}
for i, f1 := range t1.FieldSlice() {
f2 := t2.Field(i)
if f1.Sym != f2.Sym || f1.Embedded != f2.Embedded || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
return false
}
if cmpTags && f1.Note != f2.Note {
return false
}
}
return true

case TFUNC:
// Check parameters and result parameters for type equality.
// We intentionally ignore receiver parameters for type
// equality, because they're never relevant.
for _, f := range types.ParamsResults {
// Loop over fields in structs, ignoring argument names.
fs1, fs2 := f(t1).FieldSlice(), f(t2).FieldSlice()
if len(fs1) != len(fs2) {
return false
}
for i, f1 := range fs1 {
f2 := fs2[i]
if f1.Isddd() != f2.Isddd() || !eqtype1(f1.Type, f2.Type, cmpTags, assumedEqual) {
return false
}
}
}
return true

case TARRAY:
if t1.NumElem() != t2.NumElem() {
return false
}

case TCHAN:
if t1.ChanDir() != t2.ChanDir() {
return false
}

case TMAP:
if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
return false
}
}

return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
}

// Are t1 and t2 equal struct types when field names are ignored?
// For deciding whether the result struct from g can be copied
// directly when compiling f(g()).
Expand All @@ -655,7 +542,7 @@ func eqtypenoname(t1 *types.Type, t2 *types.Type) bool {
}
for i, f1 := range t1.FieldSlice() {
f2 := t2.Field(i)
if !eqtype(f1.Type, f2.Type) {
if !types.Identical(f1.Type, f2.Type) {
return false
}
}
Expand All @@ -678,7 +565,7 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op {
}

// 1. src type is identical to dst.
if eqtype(src, dst) {
if types.Identical(src, dst) {
return OCONVNOP
}

Expand All @@ -689,7 +576,7 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op {
// we want to recompute the itab. Recomputing the itab ensures
// that itabs are unique (thus an interface with a compile-time
// type I has an itab with interface type I).
if eqtype(src.Orig, dst.Orig) {
if types.Identical(src.Orig, dst.Orig) {
if src.IsEmptyInterface() {
// Conversion between two empty interfaces
// requires no code.
Expand Down Expand Up @@ -757,7 +644,7 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op {
// src and dst have identical element types, and
// either src or dst is not a named type.
if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
if eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
return OCONVNOP
}
}
Expand Down Expand Up @@ -828,14 +715,14 @@ func convertop(src *types.Type, dst *types.Type, why *string) Op {
}

// 2. Ignoring struct tags, src and dst have identical underlying types.
if eqtypeIgnoreTags(src.Orig, dst.Orig) {
if types.IdenticalIgnoreTags(src.Orig, dst.Orig) {
return OCONVNOP
}

// 3. src and dst are unnamed pointer types and, ignoring struct tags,
// their base types have identical underlying types.
if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil {
if eqtypeIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
return OCONVNOP
}
}
Expand Down Expand Up @@ -938,7 +825,7 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
}
}

if eqtype(n.Type, t) {
if types.Identical(n.Type, t) {
return n
}

Expand Down Expand Up @@ -1804,7 +1691,7 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
return false
}
tm := tms[i]
if !eqtype(tm.Type, im.Type) {
if !types.Identical(tm.Type, im.Type) {
*m = im
*samename = tm
*ptr = 0
Expand Down Expand Up @@ -1836,7 +1723,7 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
return false
}
tm := tms[i]
if tm.Nointerface() || !eqtype(tm.Type, im.Type) {
if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
*m = im
*samename = tm
*ptr = 0
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/gc/swt.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ Outer:
continue
}
for _, n := range prev {
if eqtype(n.Left.Type, c.node.Left.Type) {
if types.Identical(n.Left.Type, c.node.Left.Type) {
yyerrorl(c.node.Pos, "duplicate case %v in type switch\n\tprevious case at %v", c.node.Left.Type, n.Line())
// avoid double-reporting errors
continue Outer
Expand Down
Loading

0 comments on commit 2d58fba

Please sign in to comment.