package gotypes
import
func (, types.Type, map[*types.TypeParam]bool, map[*types.TypeParam]types.Type) bool {
= types.Unalias()
= types.Unalias()
if , := .(*types.TypeParam); && [] {
if , := []; {
return types.Identical(, )
}
[] =
return true
}
if !MentionsParams(, ) {
return types.Identical(, )
}
switch p := .(type) {
case *types.Pointer:
, := .(*types.Pointer)
return && (.Elem(), .Elem(), , )
case *types.Slice:
, := .(*types.Slice)
return && (.Elem(), .Elem(), , )
case *types.Array:
, := .(*types.Array)
return && .Len() == .Len() && (.Elem(), .Elem(), , )
case *types.Chan:
, := .(*types.Chan)
return && .Dir() == .Dir() && (.Elem(), .Elem(), , )
case *types.Map:
, := .(*types.Map)
return && (.Key(), .Key(), , ) && (.Elem(), .Elem(), , )
case *types.Named:
, := .(*types.Named)
if ! || !types.Identical(.Origin(), .Origin()) {
return false
}
, := .TypeArgs(), .TypeArgs()
if .Len() != .Len() {
return false
}
for := range .Len() {
if !(.At(), .At(), , ) {
return false
}
}
return true
case *types.Signature:
, := .(*types.Signature)
return && .Variadic() == .Variadic() &&
unifyTuple(.Params(), .Params(), , ) &&
unifyTuple(.Results(), .Results(), , )
case *types.Struct:
, := .(*types.Struct)
if ! || .NumFields() != .NumFields() {
return false
}
for := range .NumFields() {
, := .Field(), .Field()
if .Id() != .Id() || .Embedded() != .Embedded() || .Tag() != .Tag() {
return false
}
if !(.Type(), .Type(), , ) {
return false
}
}
return true
case *types.Interface:
, := .(*types.Interface)
if ! || .NumMethods() != .NumMethods() {
return false
}
for := range .NumMethods() {
, := .Method(), .Method()
if .Id() != .Id() || !(.Type(), .Type(), , ) {
return false
}
}
return true
default:
return types.Identical(, )
}
}
func (, *types.Tuple, map[*types.TypeParam]bool, map[*types.TypeParam]types.Type) bool {
if .Len() != .Len() {
return false
}
for := range .Len() {
if !Unify(.At().Type(), .At().Type(), , ) {
return false
}
}
return true
}
func ( types.Type, map[*types.TypeParam]bool) bool {
return typeContains(, &Set[types.Type]{}, func( types.Type) bool {
, := .(*types.TypeParam)
return && []
})
}
func ( types.Type, *types.TypeParam) bool {
return typeContains(, &Set[types.Type]{}, func( types.Type) bool {
, := .(*types.TypeParam)
return && ==
})
}
func ( types.Type, map[*types.TypeParam]bool) bool {
, := types.Unalias().(*types.TypeParam)
return && []
}
func ( types.Type, map[*types.TypeParam]bool) bool {
, := types.Unalias().(*types.Pointer)
return && IsBareTypeParam(.Elem(), )
}
func ( types.Type) int {
return typeDepthRec(, &Set[types.Type]{})
}
func ( types.Type, *Set[types.Type]) int {
= types.Unalias()
if !.Add() {
return 0
}
switch u := .(type) {
case *types.Pointer:
return 1 + (.Elem(), )
case *types.Slice:
return 1 + (.Elem(), )
case *types.Array:
return 1 + (.Elem(), )
case *types.Chan:
return 1 + (.Elem(), )
case *types.Map:
return 1 + max((.Key(), ), (.Elem(), ))
case *types.Named:
:= 0
if := .TypeArgs(); != nil {
for := range .Types() {
= max(, (, ))
}
}
return 1 +
case *types.Signature:
:= 0
for := range .Params().Variables() {
= max(, (.Type(), ))
}
for := range .Results().Variables() {
= max(, (.Type(), ))
}
return 1 +
case *types.Struct:
:= 0
for := range .Fields() {
= max(, (.Type(), ))
}
return 1 +
case *types.Interface:
:= 0
for := range .ExplicitMethods() {
= max(, (.Type(), ))
}
for := range .EmbeddedTypes() {
= max(, (, ))
}
return 1 +
}
return 1
}