github.com/AndrienkoAleksandr/go@v0.0.19/src/go/types/predicates.go (about) 1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. 2 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // This file implements commonly used type predicates. 8 9 package types 10 11 // The isX predicates below report whether t is an X. 12 // If t is a type parameter the result is false; i.e., 13 // these predicates don't look inside a type parameter. 14 15 func isBoolean(t Type) bool { return isBasic(t, IsBoolean) } 16 func isInteger(t Type) bool { return isBasic(t, IsInteger) } 17 func isUnsigned(t Type) bool { return isBasic(t, IsUnsigned) } 18 func isFloat(t Type) bool { return isBasic(t, IsFloat) } 19 func isComplex(t Type) bool { return isBasic(t, IsComplex) } 20 func isNumeric(t Type) bool { return isBasic(t, IsNumeric) } 21 func isString(t Type) bool { return isBasic(t, IsString) } 22 func isIntegerOrFloat(t Type) bool { return isBasic(t, IsInteger|IsFloat) } 23 func isConstType(t Type) bool { return isBasic(t, IsConstType) } 24 25 // isBasic reports whether under(t) is a basic type with the specified info. 26 // If t is a type parameter the result is false; i.e., 27 // isBasic does not look inside a type parameter. 28 func isBasic(t Type, info BasicInfo) bool { 29 u, _ := under(t).(*Basic) 30 return u != nil && u.info&info != 0 31 } 32 33 // The allX predicates below report whether t is an X. 34 // If t is a type parameter the result is true if isX is true 35 // for all specified types of the type parameter's type set. 36 // allX is an optimized version of isX(coreType(t)) (which 37 // is the same as underIs(t, isX)). 38 39 func allBoolean(t Type) bool { return allBasic(t, IsBoolean) } 40 func allInteger(t Type) bool { return allBasic(t, IsInteger) } 41 func allUnsigned(t Type) bool { return allBasic(t, IsUnsigned) } 42 func allNumeric(t Type) bool { return allBasic(t, IsNumeric) } 43 func allString(t Type) bool { return allBasic(t, IsString) } 44 func allOrdered(t Type) bool { return allBasic(t, IsOrdered) } 45 func allNumericOrString(t Type) bool { return allBasic(t, IsNumeric|IsString) } 46 47 // allBasic reports whether under(t) is a basic type with the specified info. 48 // If t is a type parameter, the result is true if isBasic(t, info) is true 49 // for all specific types of the type parameter's type set. 50 // allBasic(t, info) is an optimized version of isBasic(coreType(t), info). 51 func allBasic(t Type, info BasicInfo) bool { 52 if tpar, _ := t.(*TypeParam); tpar != nil { 53 return tpar.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) }) 54 } 55 return isBasic(t, info) 56 } 57 58 // hasName reports whether t has a name. This includes 59 // predeclared types, defined types, and type parameters. 60 // hasName may be called with types that are not fully set up. 61 func hasName(t Type) bool { 62 switch t.(type) { 63 case *Basic, *Named, *TypeParam: 64 return true 65 } 66 return false 67 } 68 69 // isTypeLit reports whether t is a type literal. 70 // This includes all non-defined types, but also basic types. 71 // isTypeLit may be called with types that are not fully set up. 72 func isTypeLit(t Type) bool { 73 switch t.(type) { 74 case *Named, *TypeParam: 75 return false 76 } 77 return true 78 } 79 80 // isTyped reports whether t is typed; i.e., not an untyped 81 // constant or boolean. isTyped may be called with types that 82 // are not fully set up. 83 func isTyped(t Type) bool { 84 // isTyped is called with types that are not fully 85 // set up. Must not call under()! 86 b, _ := t.(*Basic) 87 return b == nil || b.info&IsUntyped == 0 88 } 89 90 // isUntyped(t) is the same as !isTyped(t). 91 func isUntyped(t Type) bool { 92 return !isTyped(t) 93 } 94 95 // IsInterface reports whether t is an interface type. 96 func IsInterface(t Type) bool { 97 _, ok := under(t).(*Interface) 98 return ok 99 } 100 101 // isNonTypeParamInterface reports whether t is an interface type but not a type parameter. 102 func isNonTypeParamInterface(t Type) bool { 103 return !isTypeParam(t) && IsInterface(t) 104 } 105 106 // isTypeParam reports whether t is a type parameter. 107 func isTypeParam(t Type) bool { 108 _, ok := t.(*TypeParam) 109 return ok 110 } 111 112 // hasEmptyTypeset reports whether t is a type parameter with an empty type set. 113 // The function does not force the computation of the type set and so is safe to 114 // use anywhere, but it may report a false negative if the type set has not been 115 // computed yet. 116 func hasEmptyTypeset(t Type) bool { 117 if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil { 118 iface, _ := safeUnderlying(tpar.bound).(*Interface) 119 return iface != nil && iface.tset != nil && iface.tset.IsEmpty() 120 } 121 return false 122 } 123 124 // isGeneric reports whether a type is a generic, uninstantiated type 125 // (generic signatures are not included). 126 // TODO(gri) should we include signatures or assert that they are not present? 127 func isGeneric(t Type) bool { 128 // A parameterized type is only generic if it doesn't have an instantiation already. 129 named, _ := t.(*Named) 130 return named != nil && named.obj != nil && named.inst == nil && named.TypeParams().Len() > 0 131 } 132 133 // Comparable reports whether values of type T are comparable. 134 func Comparable(T Type) bool { 135 return comparable(T, true, nil, nil) 136 } 137 138 // If dynamic is set, non-type parameter interfaces are always comparable. 139 // If reportf != nil, it may be used to report why T is not comparable. 140 func comparable(T Type, dynamic bool, seen map[Type]bool, reportf func(string, ...interface{})) bool { 141 if seen[T] { 142 return true 143 } 144 if seen == nil { 145 seen = make(map[Type]bool) 146 } 147 seen[T] = true 148 149 switch t := under(T).(type) { 150 case *Basic: 151 // assume invalid types to be comparable 152 // to avoid follow-up errors 153 return t.kind != UntypedNil 154 case *Pointer, *Chan: 155 return true 156 case *Struct: 157 for _, f := range t.fields { 158 if !comparable(f.typ, dynamic, seen, nil) { 159 if reportf != nil { 160 reportf("struct containing %s cannot be compared", f.typ) 161 } 162 return false 163 } 164 } 165 return true 166 case *Array: 167 if !comparable(t.elem, dynamic, seen, nil) { 168 if reportf != nil { 169 reportf("%s cannot be compared", t) 170 } 171 return false 172 } 173 return true 174 case *Interface: 175 if dynamic && !isTypeParam(T) || t.typeSet().IsComparable(seen) { 176 return true 177 } 178 if reportf != nil { 179 if t.typeSet().IsEmpty() { 180 reportf("empty type set") 181 } else { 182 reportf("incomparable types in type set") 183 } 184 } 185 // fallthrough 186 } 187 return false 188 } 189 190 // hasNil reports whether type t includes the nil value. 191 func hasNil(t Type) bool { 192 switch u := under(t).(type) { 193 case *Basic: 194 return u.kind == UnsafePointer 195 case *Slice, *Pointer, *Signature, *Map, *Chan: 196 return true 197 case *Interface: 198 return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool { 199 return u != nil && hasNil(u) 200 }) 201 } 202 return false 203 } 204 205 // An ifacePair is a node in a stack of interface type pairs compared for identity. 206 type ifacePair struct { 207 x, y *Interface 208 prev *ifacePair 209 } 210 211 func (p *ifacePair) identical(q *ifacePair) bool { 212 return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x 213 } 214 215 // A comparer is used to compare types. 216 type comparer struct { 217 ignoreTags bool // if set, identical ignores struct tags 218 ignoreInvalids bool // if set, identical treats an invalid type as identical to any type 219 } 220 221 // For changes to this code the corresponding changes should be made to unifier.nify. 222 func (c *comparer) identical(x, y Type, p *ifacePair) bool { 223 if x == y { 224 return true 225 } 226 227 if c.ignoreInvalids && (x == Typ[Invalid] || y == Typ[Invalid]) { 228 return true 229 } 230 231 switch x := x.(type) { 232 case *Basic: 233 // Basic types are singletons except for the rune and byte 234 // aliases, thus we cannot solely rely on the x == y check 235 // above. See also comment in TypeName.IsAlias. 236 if y, ok := y.(*Basic); ok { 237 return x.kind == y.kind 238 } 239 240 case *Array: 241 // Two array types are identical if they have identical element types 242 // and the same array length. 243 if y, ok := y.(*Array); ok { 244 // If one or both array lengths are unknown (< 0) due to some error, 245 // assume they are the same to avoid spurious follow-on errors. 246 return (x.len < 0 || y.len < 0 || x.len == y.len) && c.identical(x.elem, y.elem, p) 247 } 248 249 case *Slice: 250 // Two slice types are identical if they have identical element types. 251 if y, ok := y.(*Slice); ok { 252 return c.identical(x.elem, y.elem, p) 253 } 254 255 case *Struct: 256 // Two struct types are identical if they have the same sequence of fields, 257 // and if corresponding fields have the same names, and identical types, 258 // and identical tags. Two embedded fields are considered to have the same 259 // name. Lower-case field names from different packages are always different. 260 if y, ok := y.(*Struct); ok { 261 if x.NumFields() == y.NumFields() { 262 for i, f := range x.fields { 263 g := y.fields[i] 264 if f.embedded != g.embedded || 265 !c.ignoreTags && x.Tag(i) != y.Tag(i) || 266 !f.sameId(g.pkg, g.name) || 267 !c.identical(f.typ, g.typ, p) { 268 return false 269 } 270 } 271 return true 272 } 273 } 274 275 case *Pointer: 276 // Two pointer types are identical if they have identical base types. 277 if y, ok := y.(*Pointer); ok { 278 return c.identical(x.base, y.base, p) 279 } 280 281 case *Tuple: 282 // Two tuples types are identical if they have the same number of elements 283 // and corresponding elements have identical types. 284 if y, ok := y.(*Tuple); ok { 285 if x.Len() == y.Len() { 286 if x != nil { 287 for i, v := range x.vars { 288 w := y.vars[i] 289 if !c.identical(v.typ, w.typ, p) { 290 return false 291 } 292 } 293 } 294 return true 295 } 296 } 297 298 case *Signature: 299 y, _ := y.(*Signature) 300 if y == nil { 301 return false 302 } 303 304 // Two function types are identical if they have the same number of 305 // parameters and result values, corresponding parameter and result types 306 // are identical, and either both functions are variadic or neither is. 307 // Parameter and result names are not required to match, and type 308 // parameters are considered identical modulo renaming. 309 310 if x.TypeParams().Len() != y.TypeParams().Len() { 311 return false 312 } 313 314 // In the case of generic signatures, we will substitute in yparams and 315 // yresults. 316 yparams := y.params 317 yresults := y.results 318 319 if x.TypeParams().Len() > 0 { 320 // We must ignore type parameter names when comparing x and y. The 321 // easiest way to do this is to substitute x's type parameters for y's. 322 xtparams := x.TypeParams().list() 323 ytparams := y.TypeParams().list() 324 325 var targs []Type 326 for i := range xtparams { 327 targs = append(targs, x.TypeParams().At(i)) 328 } 329 smap := makeSubstMap(ytparams, targs) 330 331 var check *Checker // ok to call subst on a nil *Checker 332 ctxt := NewContext() // need a non-nil Context for the substitution below 333 334 // Constraints must be pair-wise identical, after substitution. 335 for i, xtparam := range xtparams { 336 ybound := check.subst(nopos, ytparams[i].bound, smap, nil, ctxt) 337 if !c.identical(xtparam.bound, ybound, p) { 338 return false 339 } 340 } 341 342 yparams = check.subst(nopos, y.params, smap, nil, ctxt).(*Tuple) 343 yresults = check.subst(nopos, y.results, smap, nil, ctxt).(*Tuple) 344 } 345 346 return x.variadic == y.variadic && 347 c.identical(x.params, yparams, p) && 348 c.identical(x.results, yresults, p) 349 350 case *Union: 351 if y, _ := y.(*Union); y != nil { 352 // TODO(rfindley): can this be reached during type checking? If so, 353 // consider passing a type set map. 354 unionSets := make(map[*Union]*_TypeSet) 355 xset := computeUnionTypeSet(nil, unionSets, nopos, x) 356 yset := computeUnionTypeSet(nil, unionSets, nopos, y) 357 return xset.terms.equal(yset.terms) 358 } 359 360 case *Interface: 361 // Two interface types are identical if they describe the same type sets. 362 // With the existing implementation restriction, this simplifies to: 363 // 364 // Two interface types are identical if they have the same set of methods with 365 // the same names and identical function types, and if any type restrictions 366 // are the same. Lower-case method names from different packages are always 367 // different. The order of the methods is irrelevant. 368 if y, ok := y.(*Interface); ok { 369 xset := x.typeSet() 370 yset := y.typeSet() 371 if xset.comparable != yset.comparable { 372 return false 373 } 374 if !xset.terms.equal(yset.terms) { 375 return false 376 } 377 a := xset.methods 378 b := yset.methods 379 if len(a) == len(b) { 380 // Interface types are the only types where cycles can occur 381 // that are not "terminated" via named types; and such cycles 382 // can only be created via method parameter types that are 383 // anonymous interfaces (directly or indirectly) embedding 384 // the current interface. Example: 385 // 386 // type T interface { 387 // m() interface{T} 388 // } 389 // 390 // If two such (differently named) interfaces are compared, 391 // endless recursion occurs if the cycle is not detected. 392 // 393 // If x and y were compared before, they must be equal 394 // (if they were not, the recursion would have stopped); 395 // search the ifacePair stack for the same pair. 396 // 397 // This is a quadratic algorithm, but in practice these stacks 398 // are extremely short (bounded by the nesting depth of interface 399 // type declarations that recur via parameter types, an extremely 400 // rare occurrence). An alternative implementation might use a 401 // "visited" map, but that is probably less efficient overall. 402 q := &ifacePair{x, y, p} 403 for p != nil { 404 if p.identical(q) { 405 return true // same pair was compared before 406 } 407 p = p.prev 408 } 409 if debug { 410 assertSortedMethods(a) 411 assertSortedMethods(b) 412 } 413 for i, f := range a { 414 g := b[i] 415 if f.Id() != g.Id() || !c.identical(f.typ, g.typ, q) { 416 return false 417 } 418 } 419 return true 420 } 421 } 422 423 case *Map: 424 // Two map types are identical if they have identical key and value types. 425 if y, ok := y.(*Map); ok { 426 return c.identical(x.key, y.key, p) && c.identical(x.elem, y.elem, p) 427 } 428 429 case *Chan: 430 // Two channel types are identical if they have identical value types 431 // and the same direction. 432 if y, ok := y.(*Chan); ok { 433 return x.dir == y.dir && c.identical(x.elem, y.elem, p) 434 } 435 436 case *Named: 437 // Two named types are identical if their type names originate 438 // in the same type declaration; if they are instantiated they 439 // must have identical type argument lists. 440 if y, ok := y.(*Named); ok { 441 // check type arguments before origins to match unifier 442 // (for correct source code we need to do all checks so 443 // order doesn't matter) 444 xargs := x.TypeArgs().list() 445 yargs := y.TypeArgs().list() 446 if len(xargs) != len(yargs) { 447 return false 448 } 449 for i, xarg := range xargs { 450 if !Identical(xarg, yargs[i]) { 451 return false 452 } 453 } 454 return indenticalOrigin(x, y) 455 } 456 457 case *TypeParam: 458 // nothing to do (x and y being equal is caught in the very beginning of this function) 459 460 case nil: 461 // avoid a crash in case of nil type 462 463 default: 464 unreachable() 465 } 466 467 return false 468 } 469 470 // identicalOrigin reports whether x and y originated in the same declaration. 471 func indenticalOrigin(x, y *Named) bool { 472 // TODO(gri) is this correct? 473 return x.Origin().obj == y.Origin().obj 474 } 475 476 // identicalInstance reports if two type instantiations are identical. 477 // Instantiations are identical if their origin and type arguments are 478 // identical. 479 func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool { 480 if len(xargs) != len(yargs) { 481 return false 482 } 483 484 for i, xa := range xargs { 485 if !Identical(xa, yargs[i]) { 486 return false 487 } 488 } 489 490 return Identical(xorig, yorig) 491 } 492 493 // Default returns the default "typed" type for an "untyped" type; 494 // it returns the incoming type for all other types. The default type 495 // for untyped nil is untyped nil. 496 func Default(t Type) Type { 497 if t, ok := t.(*Basic); ok { 498 switch t.kind { 499 case UntypedBool: 500 return Typ[Bool] 501 case UntypedInt: 502 return Typ[Int] 503 case UntypedRune: 504 return universeRune // use 'rune' name 505 case UntypedFloat: 506 return Typ[Float64] 507 case UntypedComplex: 508 return Typ[Complex128] 509 case UntypedString: 510 return Typ[String] 511 } 512 } 513 return t 514 } 515 516 // maxType returns the "largest" type that encompasses both x and y. 517 // If x and y are different untyped numeric types, the result is the type of x or y 518 // that appears later in this list: integer, rune, floating-point, complex. 519 // Otherwise, if x != y, the result is nil. 520 func maxType(x, y Type) Type { 521 // We only care about untyped types (for now), so == is good enough. 522 // TODO(gri) investigate generalizing this function to simplify code elsewhere 523 if x == y { 524 return x 525 } 526 if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) { 527 // untyped types are basic types 528 if x.(*Basic).kind > y.(*Basic).kind { 529 return x 530 } 531 return y 532 } 533 return nil 534 }