// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.// Source: ../../cmd/compile/internal/types2/predicates.go// Copyright 2012 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// This file implements commonly used type predicates.package types// isValid reports whether t is a valid type.func isValid( Type) bool { returnUnalias() != Typ[Invalid] }// The isX predicates below report whether t is an X.// If t is a type parameter the result is false; i.e.,// these predicates don't look inside a type parameter.func isBoolean( Type) bool { returnisBasic(, IsBoolean) }func isInteger( Type) bool { returnisBasic(, IsInteger) }func isUnsigned( Type) bool { returnisBasic(, IsUnsigned) }func isFloat( Type) bool { returnisBasic(, IsFloat) }func isComplex( Type) bool { returnisBasic(, IsComplex) }func isNumeric( Type) bool { returnisBasic(, IsNumeric) }func isString( Type) bool { returnisBasic(, IsString) }func isIntegerOrFloat( Type) bool { returnisBasic(, IsInteger|IsFloat) }func isConstType( Type) bool { returnisBasic(, IsConstType) }// isBasic reports whether under(t) is a basic type with the specified info.// If t is a type parameter the result is false; i.e.,// isBasic does not look inside a type parameter.func isBasic( Type, BasicInfo) bool { , := under().(*Basic)return != nil && .info& != 0}// The allX predicates below report whether t is an X.// If t is a type parameter the result is true if isX is true// for all specified types of the type parameter's type set.// allX is an optimized version of isX(coreType(t)) (which// is the same as underIs(t, isX)).func allBoolean( Type) bool { returnallBasic(, IsBoolean) }func allInteger( Type) bool { returnallBasic(, IsInteger) }func allUnsigned( Type) bool { returnallBasic(, IsUnsigned) }func allNumeric( Type) bool { returnallBasic(, IsNumeric) }func allString( Type) bool { returnallBasic(, IsString) }func allOrdered( Type) bool { returnallBasic(, IsOrdered) }func allNumericOrString( Type) bool { returnallBasic(, IsNumeric|IsString) }// allBasic reports whether under(t) is a basic type with the specified info.// If t is a type parameter, the result is true if isBasic(t, info) is true// for all specific types of the type parameter's type set.// allBasic(t, info) is an optimized version of isBasic(coreType(t), info).func allBasic( Type, BasicInfo) bool {if , := Unalias().(*TypeParam); != nil {return .is(func( *term) bool { return != nil && isBasic(.typ, ) }) }returnisBasic(, )}// hasName reports whether t has a name. This includes// predeclared types, defined types, and type parameters.// hasName may be called with types that are not fully set up.func hasName( Type) bool {switchUnalias().(type) {case *Basic, *Named, *TypeParam:returntrue }returnfalse}// isTypeLit reports whether t is a type literal.// This includes all non-defined types, but also basic types.// isTypeLit may be called with types that are not fully set up.func isTypeLit( Type) bool {switchUnalias().(type) {case *Named, *TypeParam:returnfalse }returntrue}// isTyped reports whether t is typed; i.e., not an untyped// constant or boolean.// Safe to call from types that are not fully set up.func isTyped( Type) bool {// Alias and named types cannot denote untyped types // so there's no need to call Unalias or under, below. , := .(*Basic)return == nil || .info&IsUntyped == 0}// isUntyped(t) is the same as !isTyped(t).// Safe to call from types that are not fully set up.func isUntyped( Type) bool {return !isTyped()}// isUntypedNumeric reports whether t is an untyped numeric type.// Safe to call from types that are not fully set up.func isUntypedNumeric( Type) bool {// Alias and named types cannot denote untyped types // so there's no need to call Unalias or under, below. , := .(*Basic)return != nil && .info&IsUntyped != 0 && .info&IsNumeric != 0}// IsInterface reports whether t is an interface type.func ( Type) bool { , := under().(*Interface)return}// isNonTypeParamInterface reports whether t is an interface type but not a type parameter.func isNonTypeParamInterface( Type) bool {return !isTypeParam() && IsInterface()}// isTypeParam reports whether t is a type parameter.func isTypeParam( Type) bool { , := Unalias().(*TypeParam)return}// hasEmptyTypeset reports whether t is a type parameter with an empty type set.// The function does not force the computation of the type set and so is safe to// use anywhere, but it may report a false negative if the type set has not been// computed yet.func hasEmptyTypeset( Type) bool {if , := Unalias().(*TypeParam); != nil && .bound != nil { , := safeUnderlying(.bound).(*Interface)return != nil && .tset != nil && .tset.IsEmpty() }returnfalse}// isGeneric reports whether a type is a generic, uninstantiated type// (generic signatures are not included).// TODO(gri) should we include signatures or assert that they are not present?func isGeneric( Type) bool {// A parameterized type is only generic if it doesn't have an instantiation already.if , := .(*Alias); != nil && .tparams != nil && .targs == nil {returntrue } := asNamed()return != nil && .obj != nil && .inst == nil && .TypeParams().Len() > 0}// Comparable reports whether values of type T are comparable.func ( Type) bool {returncomparable(, true, nil, nil)}// If dynamic is set, non-type parameter interfaces are always comparable.// If reportf != nil, it may be used to report why T is not comparable.func comparable( Type, bool, map[Type]bool, func(string, ...interface{})) bool {if [] {returntrue }if == nil { = make(map[Type]bool) } [] = trueswitch t := under().(type) {case *Basic:// assume invalid types to be comparable // to avoid follow-up errorsreturn .kind != UntypedNilcase *Pointer, *Chan:returntruecase *Struct:for , := range .fields {if !(.typ, , , nil) {if != nil { ("struct containing %s cannot be compared", .typ) }returnfalse } }returntruecase *Array:if !(.elem, , , nil) {if != nil { ("%s cannot be compared", ) }returnfalse }returntruecase *Interface:if && !isTypeParam() || .typeSet().IsComparable() {returntrue }if != nil {if .typeSet().IsEmpty() { ("empty type set") } else { ("incomparable types in type set") } }// fallthrough }returnfalse}// hasNil reports whether type t includes the nil value.func hasNil( Type) bool {switch u := under().(type) {case *Basic:return .kind == UnsafePointercase *Slice, *Pointer, *Signature, *Map, *Chan:returntruecase *Interface:return !isTypeParam() || .typeSet().underIs(func( Type) bool {return != nil && () }) }returnfalse}// samePkg reports whether packages a and b are the same.func samePkg(, *Package) bool {// package is nil for objects in universe scopeif == nil || == nil {return == }// a != nil && b != nilreturn .path == .path}// An ifacePair is a node in a stack of interface type pairs compared for identity.type ifacePair struct { x, y *Interface prev *ifacePair}func ( *ifacePair) ( *ifacePair) bool {return .x == .x && .y == .y || .x == .y && .y == .x}// A comparer is used to compare types.type comparer struct { ignoreTags bool// if set, identical ignores struct tags ignoreInvalids bool// if set, identical treats an invalid type as identical to any type}// For changes to this code the corresponding changes should be made to unifier.nify.func ( *comparer) (, Type, *ifacePair) bool { = Unalias() = Unalias()if == {returntrue }if .ignoreInvalids && (!isValid() || !isValid()) {returntrue }switch x := .(type) {case *Basic:// Basic types are singletons except for the rune and byte // aliases, thus we cannot solely rely on the x == y check // above. See also comment in TypeName.IsAlias.if , := .(*Basic); {return .kind == .kind }case *Array:// Two array types are identical if they have identical element types // and the same array length.if , := .(*Array); {// If one or both array lengths are unknown (< 0) due to some error, // assume they are the same to avoid spurious follow-on errors.return (.len < 0 || .len < 0 || .len == .len) && .(.elem, .elem, ) }case *Slice:// Two slice types are identical if they have identical element types.if , := .(*Slice); {return .(.elem, .elem, ) }case *Struct:// Two struct types are identical if they have the same sequence of fields, // and if corresponding fields have the same names, and identical types, // and identical tags. Two embedded fields are considered to have the same // name. Lower-case field names from different packages are always different.if , := .(*Struct); {if .NumFields() == .NumFields() {for , := range .fields { := .fields[]if .embedded != .embedded || !.ignoreTags && .Tag() != .Tag() || !.sameId(.pkg, .name, false) || !.(.typ, .typ, ) {returnfalse } }returntrue } }case *Pointer:// Two pointer types are identical if they have identical base types.if , := .(*Pointer); {return .(.base, .base, ) }case *Tuple:// Two tuples types are identical if they have the same number of elements // and corresponding elements have identical types.if , := .(*Tuple); {if .Len() == .Len() {if != nil {for , := range .vars { := .vars[]if !.(.typ, .typ, ) {returnfalse } } }returntrue } }case *Signature: , := .(*Signature)if == nil {returnfalse }// Two function types are identical if they have the same number of // parameters and result values, corresponding parameter and result types // are identical, and either both functions are variadic or neither is. // Parameter and result names are not required to match, and type // parameters are considered identical modulo renaming.if .TypeParams().Len() != .TypeParams().Len() {returnfalse }// In the case of generic signatures, we will substitute in yparams and // yresults. := .params := .resultsif .TypeParams().Len() > 0 {// We must ignore type parameter names when comparing x and y. The // easiest way to do this is to substitute x's type parameters for y's. := .TypeParams().list() := .TypeParams().list()var []Typefor := range { = append(, .TypeParams().At()) } := makeSubstMap(, )var *Checker// ok to call subst on a nil *Checker := NewContext() // need a non-nil Context for the substitution below// Constraints must be pair-wise identical, after substitution.for , := range { := .subst(nopos, [].bound, , nil, )if !.(.bound, , ) {returnfalse } } = .subst(nopos, .params, , nil, ).(*Tuple) = .subst(nopos, .results, , nil, ).(*Tuple) }return .variadic == .variadic && .(.params, , ) && .(.results, , )case *Union:if , := .(*Union); != nil {// TODO(rfindley): can this be reached during type checking? If so, // consider passing a type set map. := make(map[*Union]*_TypeSet) := computeUnionTypeSet(nil, , nopos, ) := computeUnionTypeSet(nil, , nopos, )return .terms.equal(.terms) }case *Interface:// Two interface types are identical if they describe the same type sets. // With the existing implementation restriction, this simplifies to: // // Two interface types are identical if they have the same set of methods with // the same names and identical function types, and if any type restrictions // are the same. Lower-case method names from different packages are always // different. The order of the methods is irrelevant.if , := .(*Interface); { := .typeSet() := .typeSet()if .comparable != .comparable {returnfalse }if !.terms.equal(.terms) {returnfalse } := .methods := .methodsiflen() == len() {// Interface types are the only types where cycles can occur // that are not "terminated" via named types; and such cycles // can only be created via method parameter types that are // anonymous interfaces (directly or indirectly) embedding // the current interface. Example: // // type T interface { // m() interface{T} // } // // If two such (differently named) interfaces are compared, // endless recursion occurs if the cycle is not detected. // // If x and y were compared before, they must be equal // (if they were not, the recursion would have stopped); // search the ifacePair stack for the same pair. // // This is a quadratic algorithm, but in practice these stacks // are extremely short (bounded by the nesting depth of interface // type declarations that recur via parameter types, an extremely // rare occurrence). An alternative implementation might use a // "visited" map, but that is probably less efficient overall. := &ifacePair{, , }for != nil {if .identical() {returntrue// same pair was compared before } = .prev }ifdebug {assertSortedMethods()assertSortedMethods() }for , := range { := []if .Id() != .Id() || !.(.typ, .typ, ) {returnfalse } }returntrue } }case *Map:// Two map types are identical if they have identical key and value types.if , := .(*Map); {return .(.key, .key, ) && .(.elem, .elem, ) }case *Chan:// Two channel types are identical if they have identical value types // and the same direction.if , := .(*Chan); {return .dir == .dir && .(.elem, .elem, ) }case *Named:// Two named types are identical if their type names originate // in the same type declaration; if they are instantiated they // must have identical type argument lists.if := asNamed(); != nil {// check type arguments before origins to match unifier // (for correct source code we need to do all checks so // order doesn't matter) := .TypeArgs().list() := .TypeArgs().list()iflen() != len() {returnfalse }for , := range {if !Identical(, []) {returnfalse } }returnidenticalOrigin(, ) }case *TypeParam:// nothing to do (x and y being equal is caught in the very beginning of this function)casenil:// avoid a crash in case of nil typedefault:panic("unreachable") }returnfalse}// identicalOrigin reports whether x and y originated in the same declaration.func identicalOrigin(, *Named) bool {// TODO(gri) is this correct?return .Origin().obj == .Origin().obj}// identicalInstance reports if two type instantiations are identical.// Instantiations are identical if their origin and type arguments are// identical.func identicalInstance( Type, []Type, Type, []Type) bool {iflen() != len() {returnfalse }for , := range {if !Identical(, []) {returnfalse } }returnIdentical(, )}// Default returns the default "typed" type for an "untyped" type;// it returns the incoming type for all other types. The default type// for untyped nil is untyped nil.func ( Type) Type {// Alias and named types cannot denote untyped types // so there's no need to call Unalias or under, below.if , := .(*Basic); != nil {switch .kind {caseUntypedBool:returnTyp[Bool]caseUntypedInt:returnTyp[Int]caseUntypedRune:returnuniverseRune// use 'rune' namecaseUntypedFloat:returnTyp[Float64]caseUntypedComplex:returnTyp[Complex128]caseUntypedString:returnTyp[String] } }return}// maxType returns the "largest" type that encompasses both x and y.// If x and y are different untyped numeric types, the result is the type of x or y// that appears later in this list: integer, rune, floating-point, complex.// Otherwise, if x != y, the result is nil.func maxType(, Type) Type {// We only care about untyped types (for now), so == is good enough. // TODO(gri) investigate generalizing this function to simplify code elsewhereif == {return }ifisUntypedNumeric() && isUntypedNumeric() {// untyped types are basic typesif .(*Basic).kind > .(*Basic).kind {return }return }returnnil}// clone makes a "flat copy" of *p and returns a pointer to the copy.func clone[ *, any]( ) { := *return &}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.