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 types
8
9import "sort"
10
11func isNamed(typ Type) bool {
12	if _, ok := typ.(*Basic); ok {
13		return ok
14	}
15	_, ok := typ.(*Named)
16	return ok
17}
18
19func isBoolean(typ Type) bool {
20	t, ok := typ.Underlying().(*Basic)
21	return ok && t.info&IsBoolean != 0
22}
23
24func isInteger(typ Type) bool {
25	t, ok := typ.Underlying().(*Basic)
26	return ok && t.info&IsInteger != 0
27}
28
29func isUnsigned(typ Type) bool {
30	t, ok := typ.Underlying().(*Basic)
31	return ok && t.info&IsUnsigned != 0
32}
33
34func isFloat(typ Type) bool {
35	t, ok := typ.Underlying().(*Basic)
36	return ok && t.info&IsFloat != 0
37}
38
39func isComplex(typ Type) bool {
40	t, ok := typ.Underlying().(*Basic)
41	return ok && t.info&IsComplex != 0
42}
43
44func isNumeric(typ Type) bool {
45	t, ok := typ.Underlying().(*Basic)
46	return ok && t.info&IsNumeric != 0
47}
48
49func isString(typ Type) bool {
50	t, ok := typ.Underlying().(*Basic)
51	return ok && t.info&IsString != 0
52}
53
54func isTyped(typ Type) bool {
55	t, ok := typ.Underlying().(*Basic)
56	return !ok || t.info&IsUntyped == 0
57}
58
59func isUntyped(typ Type) bool {
60	t, ok := typ.Underlying().(*Basic)
61	return ok && t.info&IsUntyped != 0
62}
63
64func isOrdered(typ Type) bool {
65	t, ok := typ.Underlying().(*Basic)
66	return ok && t.info&IsOrdered != 0
67}
68
69func isConstType(typ Type) bool {
70	t, ok := typ.Underlying().(*Basic)
71	return ok && t.info&IsConstType != 0
72}
73
74// IsInterface reports whether typ is an interface type.
75func IsInterface(typ Type) bool {
76	_, ok := typ.Underlying().(*Interface)
77	return ok
78}
79
80// Comparable reports whether values of type T are comparable.
81func Comparable(T Type) bool {
82	switch t := T.Underlying().(type) {
83	case *Basic:
84		// assume invalid types to be comparable
85		// to avoid follow-up errors
86		return t.kind != UntypedNil
87	case *Pointer, *Interface, *Chan:
88		return true
89	case *Struct:
90		for _, f := range t.fields {
91			if !Comparable(f.typ) {
92				return false
93			}
94		}
95		return true
96	case *Array:
97		return Comparable(t.elem)
98	}
99	return false
100}
101
102// hasNil reports whether a type includes the nil value.
103func hasNil(typ Type) bool {
104	switch t := typ.Underlying().(type) {
105	case *Basic:
106		return t.kind == UnsafePointer
107	case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
108		return true
109	}
110	return false
111}
112
113// Identical reports whether x and y are identical types.
114// Receivers of Signature types are ignored.
115func Identical(x, y Type) bool {
116	return identical(x, y, true, nil)
117}
118
119// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
120// Receivers of Signature types are ignored.
121func IdenticalIgnoreTags(x, y Type) bool {
122	return identical(x, y, false, nil)
123}
124
125// An ifacePair is a node in a stack of interface type pairs compared for identity.
126type ifacePair struct {
127	x, y *Interface
128	prev *ifacePair
129}
130
131func (p *ifacePair) identical(q *ifacePair) bool {
132	return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
133}
134
135func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
136	if x == y {
137		return true
138	}
139
140	switch x := x.(type) {
141	case *Basic:
142		// Basic types are singletons except for the rune and byte
143		// aliases, thus we cannot solely rely on the x == y check
144		// above. See also comment in TypeName.IsAlias.
145		if y, ok := y.(*Basic); ok {
146			return x.kind == y.kind
147		}
148
149	case *Array:
150		// Two array types are identical if they have identical element types
151		// and the same array length.
152		if y, ok := y.(*Array); ok {
153			// If one or both array lengths are unknown (< 0) due to some error,
154			// assume they are the same to avoid spurious follow-on errors.
155			return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p)
156		}
157
158	case *Slice:
159		// Two slice types are identical if they have identical element types.
160		if y, ok := y.(*Slice); ok {
161			return identical(x.elem, y.elem, cmpTags, p)
162		}
163
164	case *Struct:
165		// Two struct types are identical if they have the same sequence of fields,
166		// and if corresponding fields have the same names, and identical types,
167		// and identical tags. Two embedded fields are considered to have the same
168		// name. Lower-case field names from different packages are always different.
169		if y, ok := y.(*Struct); ok {
170			if x.NumFields() == y.NumFields() {
171				for i, f := range x.fields {
172					g := y.fields[i]
173					if f.embedded != g.embedded ||
174						cmpTags && x.Tag(i) != y.Tag(i) ||
175						!f.sameId(g.pkg, g.name) ||
176						!identical(f.typ, g.typ, cmpTags, p) {
177						return false
178					}
179				}
180				return true
181			}
182		}
183
184	case *Pointer:
185		// Two pointer types are identical if they have identical base types.
186		if y, ok := y.(*Pointer); ok {
187			return identical(x.base, y.base, cmpTags, p)
188		}
189
190	case *Tuple:
191		// Two tuples types are identical if they have the same number of elements
192		// and corresponding elements have identical types.
193		if y, ok := y.(*Tuple); ok {
194			if x.Len() == y.Len() {
195				if x != nil {
196					for i, v := range x.vars {
197						w := y.vars[i]
198						if !identical(v.typ, w.typ, cmpTags, p) {
199							return false
200						}
201					}
202				}
203				return true
204			}
205		}
206
207	case *Signature:
208		// Two function types are identical if they have the same number of parameters
209		// and result values, corresponding parameter and result types are identical,
210		// and either both functions are variadic or neither is. Parameter and result
211		// names are not required to match.
212		if y, ok := y.(*Signature); ok {
213			return x.variadic == y.variadic &&
214				identical(x.params, y.params, cmpTags, p) &&
215				identical(x.results, y.results, cmpTags, p)
216		}
217
218	case *Interface:
219		// Two interface types are identical if they have the same set of methods with
220		// the same names and identical function types. Lower-case method names from
221		// different packages are always different. The order of the methods is irrelevant.
222		if y, ok := y.(*Interface); ok {
223			a := x.allMethods
224			b := y.allMethods
225			if len(a) == len(b) {
226				// Interface types are the only types where cycles can occur
227				// that are not "terminated" via named types; and such cycles
228				// can only be created via method parameter types that are
229				// anonymous interfaces (directly or indirectly) embedding
230				// the current interface. Example:
231				//
232				//    type T interface {
233				//        m() interface{T}
234				//    }
235				//
236				// If two such (differently named) interfaces are compared,
237				// endless recursion occurs if the cycle is not detected.
238				//
239				// If x and y were compared before, they must be equal
240				// (if they were not, the recursion would have stopped);
241				// search the ifacePair stack for the same pair.
242				//
243				// This is a quadratic algorithm, but in practice these stacks
244				// are extremely short (bounded by the nesting depth of interface
245				// type declarations that recur via parameter types, an extremely
246				// rare occurrence). An alternative implementation might use a
247				// "visited" map, but that is probably less efficient overall.
248				q := &ifacePair{x, y, p}
249				for p != nil {
250					if p.identical(q) {
251						return true // same pair was compared before
252					}
253					p = p.prev
254				}
255				if debug {
256					assert(sort.IsSorted(byUniqueMethodName(a)))
257					assert(sort.IsSorted(byUniqueMethodName(b)))
258				}
259				for i, f := range a {
260					g := b[i]
261					if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) {
262						return false
263					}
264				}
265				return true
266			}
267		}
268
269	case *Map:
270		// Two map types are identical if they have identical key and value types.
271		if y, ok := y.(*Map); ok {
272			return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p)
273		}
274
275	case *Chan:
276		// Two channel types are identical if they have identical value types
277		// and the same direction.
278		if y, ok := y.(*Chan); ok {
279			return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p)
280		}
281
282	case *Named:
283		// Two named types are identical if their type names originate
284		// in the same type declaration.
285		if y, ok := y.(*Named); ok {
286			return x.obj == y.obj
287		}
288
289	case nil:
290
291	default:
292		unreachable()
293	}
294
295	return false
296}
297
298// Default returns the default "typed" type for an "untyped" type;
299// it returns the incoming type for all other types. The default type
300// for untyped nil is untyped nil.
301//
302func Default(typ Type) Type {
303	if t, ok := typ.(*Basic); ok {
304		switch t.kind {
305		case UntypedBool:
306			return Typ[Bool]
307		case UntypedInt:
308			return Typ[Int]
309		case UntypedRune:
310			return universeRune // use 'rune' name
311		case UntypedFloat:
312			return Typ[Float64]
313		case UntypedComplex:
314			return Typ[Complex128]
315		case UntypedString:
316			return Typ[String]
317		}
318	}
319	return typ
320}
321