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