Involved Source Files
Package typeparams contains common utilities for writing tools that interact
with generic Go code, as introduced with Go 1.18.
Many of the types and functions in this package are proxies for the new APIs
introduced in the standard library with Go 1.18. For example, the
typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec
function returns the value of the go/ast.TypeSpec.TypeParams field. At Go
versions older than 1.18 these helpers are implemented as stubs, allowing
users of this package to write code that handles generic constructs inline,
even if the Go version being used to compile does not support generics.
Additionally, this package contains common utilities for working with the
new generic constructs, to supplement the standard library APIs. Notably,
the StructuralTerms API computes a minimal representation of the structural
restrictions on a type parameter.
An external version of these APIs is available in the
golang.org/x/exp/typeparams module.
coretype.goenabled_go118.gonormalize.gotermlist.gotypeparams_go118.gotypeterm.go
Package-Level Type Names (total 11, in which 8 are exported)
A termSet holds the normalized set of terms for a given type.
The name termSet is intentionally distinct from 'type set': a type set is
all types that implement a type (and includes method restrictions), whereas
a term set just represents the structural restrictions on a type.
completebooltermstermlist
func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error)
func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error)
Package-Level Functions (total 35, in which 30 are exported)
CoreType returns the core type of T or nil if T does not have a core type.
See https://go.dev/ref/spec#Core_types for the definition of a core type.
ForFuncType returns n.TypeParams.
ForNamed extracts the (possibly empty) type parameter object list from
named.
ForSignature returns sig.TypeParams()
ForTypeSpec returns n.TypeParams.
GenericAssignableTo is a generalization of types.AssignableTo that
implements the following rule for uninstantiated generic types:
If V and T are generic named types, then V is considered assignable to T if,
for every possible instantation of V[A_1, ..., A_N], the instantiation
T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N].
If T has structural constraints, they must be satisfied by V.
For example, consider the following type declarations:
type Interface[T any] interface {
Accept(T)
}
type Container[T any] struct {
Element T
}
func (c Container[T]) Accept(t T) { c.Element = t }
In this case, GenericAssignableTo reports that instantiations of Container
are assignable to the corresponding instantiation of Interface.
GetInstances returns info.Instances.
InitInstanceInfo initializes info to record information about type and
function instances.
Instantiate calls types.Instantiate.
InterfaceTermSet computes the normalized terms for a constraint interface,
returning an error if the term set cannot be computed or is empty. In the
latter case, the error will be ErrEmptyTypeSet.
See the documentation of StructuralTerms for more information on
normalization.
IsComparable calls iface.IsComparable().
IsImplicit calls iface.IsImplicit().
IsMethodSet calls iface.IsMethodSet().
IsTypeParam reports whether t is a type parameter.
MarkImplicit calls iface.MarkImplicit().
NamedTypeArgs returns named.TypeArgs().
NamedTypeOrigin returns named.Orig().
NewContext calls types.NewContext.
NewSignatureType calls types.NewSignatureType.
NewTerm calls types.NewTerm.
NewTypeParam calls types.NewTypeParam.
NewUnion calls types.NewUnion.
OriginMethod returns the origin method associated with the method fn.
For methods on a non-generic receiver base type, this is just
fn. However, for methods with a generic receiver, OriginMethod returns the
corresponding method in the method set of the origin type.
As a special case, if fn is not a method (has no receiver), OriginMethod
returns fn.
PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on
the cardinality of indices. Calling PackIndexExpr with len(indices) == 0
will panic.
RecvTypeParams returns sig.RecvTypeParams().
SetForNamed sets the type params tparams on n. Each tparam must be of
dynamic type *types.TypeParam.
StructuralTerms returns a slice of terms representing the normalized
structural type restrictions of a type parameter, if any.
Structural type restrictions of a type parameter are created via
non-interface types embedded in its constraint interface (directly, or via a
chain of interface embeddings). For example, in the declaration
type T[P interface{~int; m()}] int
the structural restriction of the type parameter P is ~int.
With interface embedding and unions, the specification of structural type
restrictions may be arbitrarily complex. For example, consider the
following:
type A interface{ ~string|~[]byte }
type B interface{ int|string }
type C interface { ~string|~int }
type T[P interface{ A|B; C }] int
In this example, the structural type restriction of P is ~string|int: A|B
expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
which when intersected with C (~string|~int) yields ~string|int.
StructuralTerms computes these expansions and reductions, producing a
"normalized" form of the embeddings. A structural restriction is normalized
if it is a single union containing no interface terms, and is minimal in the
sense that removing any term changes the set of types satisfying the
constraint. It is left as a proof for the reader that, modulo sorting, there
is exactly one such normalized form.
Because the minimal representation always takes this form, StructuralTerms
returns a slice of tilde terms corresponding to the terms of the union in
the normalized structural restriction. An error is returned if the
constraint interface is invalid, exceeds complexity bounds, or has an empty
type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet.
StructuralTerms makes no guarantees about the order of terms, except that it
is deterministic.
UnionTermSet computes the normalized terms for a union, returning an error
if the term set cannot be computed or is empty. In the latter case, the
error will be ErrEmptyTypeSet.
See the documentation of StructuralTerms for more information on
normalization.
UnpackIndexExpr extracts data from AST nodes that represent index
expressions.
For an ast.IndexExpr, the resulting indices slice will contain exactly one
index expression. For an ast.IndexListExpr (go1.18+), it may have a variable
number of index expressions.
For nodes that don't represent index expressions, the first return value of
UnpackIndexExpr will be nil.
_NormalTerms returns a slice of terms representing the normalized structural
type restrictions of a type, if any.
For all types other than *types.TypeParam, *types.Interface, and
*types.Union, this is just a single term with Tilde() == false and
Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
below.
Structural type restrictions of a type parameter are created via
non-interface types embedded in its constraint interface (directly, or via a
chain of interface embeddings). For example, in the declaration type
T[P interface{~int; m()}] int the structural restriction of the type
parameter P is ~int.
With interface embedding and unions, the specification of structural type
restrictions may be arbitrarily complex. For example, consider the
following:
type A interface{ ~string|~[]byte }
type B interface{ int|string }
type C interface { ~string|~int }
type T[P interface{ A|B; C }] int
In this example, the structural type restriction of P is ~string|int: A|B
expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
which when intersected with C (~string|~int) yields ~string|int.
_NormalTerms computes these expansions and reductions, producing a
"normalized" form of the embeddings. A structural restriction is normalized
if it is a single union containing no interface terms, and is minimal in the
sense that removing any term changes the set of types satisfying the
constraint. It is left as a proof for the reader that, modulo sorting, there
is exactly one such normalized form.
Because the minimal representation always takes this form, _NormalTerms
returns a slice of tilde terms corresponding to the terms of the union in
the normalized structural restriction. An error is returned if the type is
invalid, exceeds complexity bounds, or has an empty type set. In the latter
case, _NormalTerms returns ErrEmptyTypeSet.
_NormalTerms makes no guarantees about the order of terms, except that it
is deterministic.