mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
[dev.typeparams] go/types: support local defined types
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>
This commit is contained in:
parent
76b39959f4
commit
ccf95f17dd
|
@ -428,14 +428,19 @@ func (subst *subster) typ(typ Type) Type {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var instanceHashing = 0
|
||||||
|
|
||||||
// TODO(gri) Eventually, this should be more sophisticated.
|
// TODO(gri) Eventually, this should be more sophisticated.
|
||||||
// It won't work correctly for locally declared types.
|
// It won't work correctly for locally declared types.
|
||||||
func instantiatedHash(typ *Named, targs []Type) string {
|
func instantiatedHash(typ *Named, targs []Type) string {
|
||||||
|
assert(instanceHashing == 0)
|
||||||
|
instanceHashing++
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
writeTypeName(&buf, typ.obj, nil)
|
writeTypeName(&buf, typ.obj, nil)
|
||||||
buf.WriteByte('[')
|
buf.WriteByte('[')
|
||||||
writeTypeList(&buf, targs, nil, nil)
|
writeTypeList(&buf, targs, nil, nil)
|
||||||
buf.WriteByte(']')
|
buf.WriteByte(']')
|
||||||
|
instanceHashing--
|
||||||
|
|
||||||
// With respect to the represented type, whether a
|
// With respect to the represented type, whether a
|
||||||
// type is fully expanded or stored as instance
|
// type is fully expanded or stored as instance
|
||||||
|
|
|
@ -348,17 +348,33 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
|
func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
|
||||||
s := "<Named w/o object>"
|
if obj == nil {
|
||||||
if obj != nil {
|
buf.WriteString("<Named w/o object>")
|
||||||
if obj.pkg != nil {
|
return
|
||||||
writePackage(buf, obj.pkg, qf)
|
}
|
||||||
}
|
if obj.pkg != nil {
|
||||||
// TODO(gri): function-local named types should be displayed
|
writePackage(buf, obj.pkg, qf)
|
||||||
// differently from named types at package level to avoid
|
}
|
||||||
// ambiguity.
|
buf.WriteString(obj.name)
|
||||||
s = 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.WriteString(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
|
func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
|
||||||
|
|
Loading…
Reference in a new issue