// 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. func CoreType(T types.Type) types.Type { … } // 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. func NormalTerms(typ types.Type) ([]*types.Term, error) { … } // Deref returns the type of the variable pointed to by t, // if t's core type is a pointer; otherwise it returns t. // // Do not assume that Deref(T)==T implies T is not a pointer: // consider "type T *T", for example. // // TODO(adonovan): ideally this would live in typesinternal, but that // creates an import cycle. Move there when we melt this package down. func Deref(t types.Type) types.Type { … } // MustDeref returns the type of the variable pointed to by t. // It panics if t's core type is not a pointer. // // TODO(adonovan): ideally this would live in typesinternal, but that // creates an import cycle. Move there when we melt this package down. func MustDeref(t types.Type) types.Type { … }