]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: eliminate typeHashing global variable
authorRobert Findley <rfindley@google.com>
Tue, 31 Aug 2021 22:15:53 +0000 (18:15 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 1 Sep 2021 00:36:05 +0000 (00:36 +0000)
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 <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

src/go/types/instantiate.go
src/go/types/subst.go
src/go/types/typestring.go

index e89f645c8fa39281ec72806e2299a1474a1d322d..ec4c61cf6224fa8065d2f81ab11628291eb8cb86 100644 (file)
@@ -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)) {
index c811f8a4df2db3c1e7ea8c0caace651dcf100c81..fb77617d0c27377ada72e65796d2c314c93c1667 100644 (file)
@@ -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
index 384122704438210fa188332c7a746eb427d3b580..3a6bb9aafc773589dfa97e35a64f809246ecb42f 100644 (file)
@@ -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("<Named w/o object>")
                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
        }