Skip to content

proposal: x/tools/go/types/typeutil: add TypeMap[V] #67161

Closed as not planned
Closed as not planned
@adonovan

Description

@adonovan

[EDIT: withdrawn in favor of this proposal:]

We propose to add a generic wrapper around typeutil.Map. The obvious name is TypeMap[V]. Only the necessary methods need to be parameterized; the remainder will be promoted from a non-exported embedding of Map.

(Aside: this technique seems quite general. If in future Map should ever sprout a method that we don't want promoted to TypeMap, but nor do we want to shadow it with a parameterized variant, it's possible for TypeMap to embed another field, of size zero, that defines a conflicting method, so the two annihilate.)

package typeutil // import "golang.org/x/tools/go/types/typeutil"

// TypeMap[V] is a generic wrapper around a [Map] from [types.Type] to V.
//
// The following methods are promoted from Map:
// [Map.SetHasher], [Map.Delete], [Map.String], [Map.Keys],
// [Map.KeysString], [Map.Len], [Map.Iterate].
type TypeMap[V any] struct{ _map }

type _map = Map // avoid exposing representation

// At returns the value corresponding to the key type,
// or zero if not present.
func (m *TypeMap[V]) At(key types.Type) (value V) {
	if m != nil {
		value, _ = m._map.At(key).(V)
	}
	return
}

// Set updates the value corresponding to the specified key type,
// and returns the previous value, or zero if the entry is new.
func (m *TypeMap[V]) Set(key types.Type, value V) (prev V) {
	if m != nil {
		prev, _ = m._map.Set(key, value).(V)
	}
	return
}

// This function would be declared in a file with a go1.23 tag:

// All returns a go1.23 iterator over the key/value entries of the map.
func (m *TypeMap[V]) All() iter.Seq2[Type, V] { ... }

[Update: I changed the declaration of All to use iter.Seq2, requiring a go1.23 build tag.]

@findleyr @griesemer

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

Declined

Relationships

None yet

Development

No branches or pull requests

Issue actions