Open
Description
[Edit: this proposal is now just for the hash function. The HashMap is another proposal.]
We propose to add the HashMap data type (a generic evolution of golang.org/x/tools/go/types/typeutil.Map) to the standard go/types
package, with the following API:
// Updated Apr 9 2025
package types // import "go/types"
// Hasher defines a hash function and equivalence relation for Types
// that is consistent with [Identical]. Hashers are stateless.
type Hasher struct{}
func (Hasher) Hash(h *maphash.Hash, t Type)
func (Hasher) Equal(x, y Type) bool
// HasherIgnoreTags defines a hash function and equivalence relation for Types
// that is consistent with [IdenticalIgnoreTags]. HasherIgnoreTags is stateless.
type HasherIgnoreTags struct{}
func (HasherIgnoreTags) Hash(h *maphash.Hash, t Type)
func (HasherIgnoreTags) Equal(x, y Type) bool
Rescinded part of the proposal:
// HashMap[V] is a mapping from Type to values of type V.
// Map keys (types) are considered equivalent if they are Identical.
// As with map[K]V, a nil *HashMap is a valid empty map.
type HashMap[V any] struct { ... }
// All returns an iterator over the key/value entries of the map in undefined order.
func (m *HashMap[V]) All() iter.Seq2[Type, V]
// At returns the map entry for the given key. It returns zero if the entry is not present.
func (m *HashMap[V]) At(key Type) V
// Delete removes th//e entry with the given key, if any. It returns true if the entry was found.
func (m *HashMap[V]) Delete(key Type) bool
// Keys returns an iterator over the map keys in undefined order.
func (m *HashMap[V]) Keys() iter.Seq[Type]
// KeysString returns a string representation of the map's key set in unspecified order.
func (m *HashMap[V]) KeysString() string
// Len returns the number of map entries.
func (m *HashMap[V]) Len() int
// Set updates the map entry for key to value, and returns the previous entry, if any.
func (m *HashMap[V]) Set(key Type, value V) (prev V)
// String returns a string representation of the map's entries in unspecified order.
// Values are printed as if by fmt.Sprint.
func (m *HashMap[V]) String() string
Some notes:
- This proposal supersedes proposal: x/tools/go/types/typeutil: add TypeMap[V] #67161, to x/tools/go/types/typeutil.Map.
- It is generic, whereas typeutil.Map is not.
- It uses idiomatic Go 1.23 iterators.
- The typeutil.Hasher type and SetHasher method are not part of this proposal. They had no performance advantage, and the statefulness turned reads into writes. The hash recursion bottoms out at named types, so most types are shallow.
- There is still no way to distinguish "m[k] is zero" from "missing"; this has never been a problem in practice.
- The Hash function does not accept a seed and thus HashMap is vulnerable to flooding. But the type checker is vulnerable to various other performance problems if an attacker controls its input.
Metadata
Metadata
Assignees
Type
Projects
Status
Active