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
}
check.typMap[h] = named
}
return named
+
case *Signature:
tparams := t.TParams()
if !check.validateTArgLen(pos, tparams.Len(), len(targs)) {
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
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
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) }
// 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)
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
}
}
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 {
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(' ')
}
}
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
}