You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: map.go
    path of file: ./repos/gomacro/go/typeutil
    
    the code of the file until where you have to start completion: // Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package typeutil defines various utilities for types, such as Map,
// a mapping from types.Type to interface{} values.
package typeutil

import (
	"bytes"
	"fmt"
	"reflect"

	"github.com/cosmos72/gomacro/go/types"
)

// Map is a hash-table-based mapping from types (types.Type) to
// arbitrary interface{} values.  The concrete types that implement
// the Type interface are pointers.  Since they are not canonicalized,
// == cannot be used to check for equivalence, and thus we cannot
// simply use a Go map.
//
// Just as with map[K]V, a nil *Map is a valid, read-only empty map.
//
// Not thread-safe.
//
type
    
func (h Hasher) hashFor(t types.Type) uint32 {
	// See Identical 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
			}
			// field order is significant
			hash = hash<<5 | hash>>27
			hash += hashString(t.Tag(i))
			hash += hashString(f.Name()) // (ignore f.Pkg)
			hash += h.Hash(f.Type())
		}
		return hash

	case *types.Pointer:
		return 9067 + 2*h.Hash(t.Elem())

	case *types.Signature:
		var hash uint32 = 9091
		if t.Variadic() {
			hash *= 8863
		}
		// PATCH: also include the receiver type
		return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) + 7*h.hashVar(t.Recv())

	case *types.Interface:
		// PATCH: consider the explicit methods and embedded interfaces, in order.
		// See Identical for rationale.
		var hash uint32 = 9103
		for i, n := 0, t.NumEmbeddeds(); i < n; i++ {
			// Embedded interfaces order is significant.
			e := t.Embedded(i)
			// Not safe with a copying GC; objects may move.
			hash = (hash<<5 | hash>>27) + 2*hashNamed(e)
		}
		for i, n := 0, t.NumExplicitMethods(); i < n; i++ {
			// Method order is significant.
			// Ignore m.Pkg().
			m := t.ExplicitMethod(i)
			// fmt.Printf("Hash for interface <%v> method %q <%v>\n", t, m.Name(), m.Type())

			hash = (hash<<5 | hash>>27) + 7*hashString(m.Name())
			if etoken, ok := m.Type().Underlying().(*types.Signature); ok {
				if etoken.Variadic() {
					hash *= 8863
				}
				// do NOT hash the receiver of an interface... it may be the interface itself
				hash += 3*h.hashTuple(etoken.Params()) + 5*h.hashTuple(etoken.Results())
			}
		}
		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 hashNamed(t)

	case *types.Tuple:
		return h.hashTuple(t)

	case nil:
		return 9133
	}
	panic(t)
}