predicates.go raw

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