]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: support local defined types
authorRob Findley <rfindley@google.com>
Fri, 16 Jul 2021 17:27:57 +0000 (13:27 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 19 Jul 2021 15:49:09 +0000 (15:49 +0000)
This is a port of CL 327170 to go/types. Tests were not ported; they can
be added later.

Change-Id: Ic9fd681ac06dd187c1715efaf882b11353bc395a
Reviewed-on: https://go-review.googlesource.com/c/go/+/335113
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/subst.go
src/go/types/typestring.go

index 41ffcd0d1e41afe84e1633690bd76b801d6c743f..d8388a948b88c5845ab8f632ddcc3081c8356838 100644 (file)
@@ -428,14 +428,19 @@ func (subst *subster) typ(typ Type) Type {
        return typ
 }
 
+var instanceHashing = 0
+
 // TODO(gri) Eventually, this should be more sophisticated.
 //           It won't work correctly for locally declared types.
 func instantiatedHash(typ *Named, targs []Type) string {
+       assert(instanceHashing == 0)
+       instanceHashing++
        var buf bytes.Buffer
        writeTypeName(&buf, typ.obj, nil)
        buf.WriteByte('[')
        writeTypeList(&buf, targs, nil, nil)
        buf.WriteByte(']')
+       instanceHashing--
 
        // With respect to the represented type, whether a
        // type is fully expanded or stored as instance
index aef5e2013bddd9cd98fdac82295568f315a64611..f348d185c55adb5e6cbfb939877984a9b84bec72 100644 (file)
@@ -348,17 +348,33 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
 }
 
 func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
-       s := "<Named w/o object>"
-       if obj != nil {
-               if obj.pkg != nil {
-                       writePackage(buf, obj.pkg, qf)
+       if obj == nil {
+               buf.WriteString("<Named w/o object>")
+               return
+       }
+       if obj.pkg != nil {
+               writePackage(buf, obj.pkg, qf)
+       }
+       buf.WriteString(obj.name)
+
+       if instanceHashing != 0 {
+               // For local defined types, use the (original!) TypeName's position
+               // to disambiguate. This is overkill, and could probably instead
+               // just be the pointer value (if we assume a non-moving GC) or
+               // a unique ID (like cmd/compile uses). But this works for now,
+               // and is convenient for debugging.
+
+               // TODO(mdempsky): I still don't fully understand why typ.orig.orig
+               // can differ from typ.orig, or whether looping more than twice is
+               // ever necessary.
+               typ := obj.typ.(*Named)
+               for typ.orig != typ {
+                       typ = typ.orig
+               }
+               if orig := typ.obj; orig.pkg != nil && orig.parent != orig.pkg.scope {
+                       fmt.Fprintf(buf, "@%q", orig.pos)
                }
-               // TODO(gri): function-local named types should be displayed
-               // differently from named types at package level to avoid
-               // ambiguity.
-               s = obj.name
        }
-       buf.WriteString(s)
 }
 
 func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {