From: Robert Findley Date: Tue, 31 Aug 2021 22:15:53 +0000 (-0400) Subject: go/types: eliminate typeHashing global variable X-Git-Tag: go1.18beta1~1542 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5cd1b847dc6e2d70e503fb44e27d0ece261ebfff;p=gostls13.git go/types: eliminate typeHashing global variable This is a port of CL 345929 to go/types. It is also a step toward making instantiation concurrency-safe. Also fix some whitespace in instantiate.go. Updates #47910 Change-Id: Icdeb227cb83eee15da6db90daab294c8c55db601 Reviewed-on: https://go-review.googlesource.com/c/go/+/346557 Trust: Robert Findley Run-TryBot: Robert Findley Reviewed-by: Robert Griesemer TryBot-Result: Go Bot --- diff --git a/src/go/types/instantiate.go b/src/go/types/instantiate.go index e89f645c8f..ec4c61cf62 100644 --- a/src/go/types/instantiate.go +++ b/src/go/types/instantiate.go @@ -121,8 +121,8 @@ func (check *Checker) instance(pos token.Pos, typ Type, targs []Type) Type { case *Named: h := typeHash(t, targs) if check != nil { - // typ may already have been instantiated with identical type arguments. In - // that case, re-use the existing instance. + // typ may already have been instantiated with identical type arguments. + // In that case, re-use the existing instance. if named := check.typMap[h]; named != nil { return named } @@ -135,6 +135,7 @@ func (check *Checker) instance(pos token.Pos, typ Type, targs []Type) Type { check.typMap[h] = named } return named + case *Signature: tparams := t.TParams() if !check.validateTArgLen(pos, tparams.Len(), len(targs)) { diff --git a/src/go/types/subst.go b/src/go/types/subst.go index c811f8a4df..fb77617d0c 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -256,8 +256,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 @@ -266,19 +264,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/go/types/typestring.go b/src/go/types/typestring.go index 3841227044..3a6bb9aafc 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -63,10 +63,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) } @@ -208,7 +213,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) @@ -292,7 +297,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 } @@ -301,7 +306,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 { @@ -335,7 +340,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(' ') } @@ -383,8 +388,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 }