// hashFor computes the hash of t. func (h Hasher) hashFor(t types.Type) uint32 { // See IsIdentical for rationale. switch t := t.(type) { case *types.Basic: return uint32(t.Kind) case *types.Array: return 9043 + 2*uint32(t.Len) + 3*h.Hash(t.Elem) case *types.Slice: return 9049 + 2*h.Hash(t.Elem) case *types.Struct: var hash uint32 = 9059 for i, n := 0, t.NumFields(); i < n; i++ { f := t.Field(i) if f.Anonymous() { hash += 8861 } hash += hashString(t.Tag(i)) hash += hashString(f.GetName()) // (ignore f.Pkg) hash += h.Hash(f.GetType()) } return hash case *types.Pointer: return 9067 + 2*h.Hash(t.Elem) case *types.Signature: var hash uint32 = 9091 if t.IsVariadic() { hash *= 8863 } return hash + 3*h.hashTuple(t.Params) + 5*h.hashTuple(t.Results) case *types.Interface: var hash uint32 = 9103 for i, n := 0, t.NumMethods(); i < n; i++ { // See go/types.identicalMethods for rationale. // Method order is not significant. // Ignore m.GetPkg(). m := t.Method(i) hash += 3*hashString(m.GetName()) + 5*h.Hash(m.GetType()) } return hash case *types.Map: return 9109 + 2*h.Hash(t.Key) + 3*h.Hash(t.Elem) case *types.Chan: return 9127 + 2*uint32(t.Dir) + 3*h.Hash(t.Elem) case *types.Named: // Not safe with a copying GC; objects may move. return uint32(uintptr(unsafe.Pointer(t.Obj))) case *types.Tuple: return h.hashTuple(t) } panic(t) }