diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go index 18a9e39300..c67538d4f0 100644 --- a/src/cmd/compile/internal/types2/subst.go +++ b/src/cmd/compile/internal/types2/subst.go @@ -253,8 +253,6 @@ func (subst *subster) typ(typ Type) Type { return typ } -var typeHashing = 0 - // typeHash returns a string representation of typ, which can be used as an exact // type hash: types that are identical produce identical string representations. // If typ is a *Named type and targs is not empty, typ is printed as if it were @@ -263,19 +261,16 @@ func typeHash(typ Type, targs []Type) string { assert(typ != nil) var buf bytes.Buffer - assert(typeHashing == 0) - typeHashing++ - w := newTypeWriter(&buf, nil) + h := newTypeHasher(&buf) if named, _ := typ.(*Named); named != nil && len(targs) > 0 { // Don't use WriteType because we need to use the provided targs // and not any targs that might already be with the *Named type. - w.typeName(named.obj) - w.typeList(targs) + h.typeName(named.obj) + h.typeList(targs) } else { assert(targs == nil) - w.typ(typ) + h.typ(typ) } - typeHashing-- if debug { // there should be no instance markers in type hashes diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go index 2110b46498..3582d183a8 100644 --- a/src/cmd/compile/internal/types2/typestring.go +++ b/src/cmd/compile/internal/types2/typestring.go @@ -62,10 +62,15 @@ type typeWriter struct { buf *bytes.Buffer seen map[Type]bool qf Qualifier + hash bool } func newTypeWriter(buf *bytes.Buffer, qf Qualifier) *typeWriter { - return &typeWriter{buf, make(map[Type]bool), qf} + return &typeWriter{buf, make(map[Type]bool), qf, false} +} + +func newTypeHasher(buf *bytes.Buffer) *typeWriter { + return &typeWriter{buf, make(map[Type]bool), nil, true} } func (w *typeWriter) byte(b byte) { w.buf.WriteByte(b) } @@ -207,7 +212,7 @@ func (w *typeWriter) typ(typ Type) { // types. Write them to aid debugging, but don't write // them when we need an instance hash: whether a type // is fully expanded or not doesn't matter for identity. - if typeHashing == 0 && t.instPos != nil { + if !w.hash && t.instPos != nil { w.byte(instanceMarker) } w.typeName(t.obj) @@ -291,7 +296,7 @@ func (w *typeWriter) tParamList(list []*TypeParam) { func (w *typeWriter) typeName(obj *TypeName) { if obj == nil { - assert(typeHashing == 0) // we need an object for type hashing + assert(!w.hash) // we need an object for type hashing w.string("") return } @@ -300,7 +305,7 @@ func (w *typeWriter) typeName(obj *TypeName) { } w.string(obj.name) - if typeHashing != 0 { + if w.hash { // For local defined types, use the (original!) TypeName's scope // numbers to disambiguate. if typ, _ := obj.typ.(*Named); typ != nil { @@ -334,7 +339,7 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) { w.string(", ") } // parameter names are ignored for type identity and thus type hashes - if typeHashing == 0 && v.name != "" { + if !w.hash && v.name != "" { w.string(v.name) w.byte(' ') } @@ -382,8 +387,8 @@ func (w *typeWriter) signature(sig *Signature) { } w.byte(' ') - if n == 1 && (typeHashing != 0 || sig.results.vars[0].name == "") { - // single unnamed result (if typeHashing, name must be ignored) + if n == 1 && (w.hash || sig.results.vars[0].name == "") { + // single unnamed result (if type hashing, name must be ignored) w.typ(sig.results.vars[0].typ) return }