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