aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-06-11 01:09:47 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-06-16 21:38:50 +0000
commit1ba2074440a9b82b6e39c42f40b9d04858aa6c75 (patch)
treedb34ccf45a9638bbd9b3ec4ceb4fec59fd99111c /src
parentdd95a4e3dbe1e060b59840efd7311e8d5e82c08c (diff)
downloadgo-1ba2074440a9b82b6e39c42f40b9d04858aa6c75.tar.gz
go-1ba2074440a9b82b6e39c42f40b9d04858aa6c75.zip
[dev.typeparams] cmd/compile/internal/types2: support local defined types
This CL changes types2's instance hashing logic to include position information for function-scope defined types as disambiguation. This isn't ideal, but it worked for getting nested.go passing. Updates #46592. Change-Id: Id83ba0001f44af69b81260306cc8b05e44fc4f09 Reviewed-on: https://go-review.googlesource.com/c/go/+/327170 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Trust: Matthew Dempsky <mdempsky@google.com> Trust: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/subst.go5
-rw-r--r--src/cmd/compile/internal/types2/typestring.go34
2 files changed, 30 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go
index dd8dd74161..3ef65c2e92 100644
--- a/src/cmd/compile/internal/types2/subst.go
+++ b/src/cmd/compile/internal/types2/subst.go
@@ -425,14 +425,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
diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go
index 07ed510d11..f08c41c2a3 100644
--- a/src/cmd/compile/internal/types2/typestring.go
+++ b/src/cmd/compile/internal/types2/typestring.go
@@ -350,17 +350,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) {