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.
5 // This file implements commonly used type predicates.
9 func isNamed(typ Type) bool {
10 if _, ok := typ.(*Basic); ok {
17 func isBoolean(typ Type) bool {
18 t, ok := typ.Underlying().(*Basic)
19 return ok && t.info&IsBoolean != 0
22 func isInteger(typ Type) bool {
23 t, ok := typ.Underlying().(*Basic)
24 return ok && t.info&IsInteger != 0
27 func isUnsigned(typ Type) bool {
28 t, ok := typ.Underlying().(*Basic)
29 return ok && t.info&IsUnsigned != 0
32 func isFloat(typ Type) bool {
33 t, ok := typ.Underlying().(*Basic)
34 return ok && t.info&IsFloat != 0
37 func isComplex(typ Type) bool {
38 t, ok := typ.Underlying().(*Basic)
39 return ok && t.info&IsComplex != 0
42 func isNumeric(typ Type) bool {
43 t, ok := typ.Underlying().(*Basic)
44 return ok && t.info&IsNumeric != 0
47 func isString(typ Type) bool {
48 t, ok := typ.Underlying().(*Basic)
49 return ok && t.info&IsString != 0
52 func isTyped(typ Type) bool {
53 t, ok := typ.Underlying().(*Basic)
54 return !ok || t.info&IsUntyped == 0
57 func isUntyped(typ Type) bool {
58 t, ok := typ.Underlying().(*Basic)
59 return ok && t.info&IsUntyped != 0
62 func isOrdered(typ Type) bool {
63 t, ok := typ.Underlying().(*Basic)
64 return ok && t.info&IsOrdered != 0
67 func isConstType(typ Type) bool {
68 t, ok := typ.Underlying().(*Basic)
69 return ok && t.info&IsConstType != 0
72 // IsInterface reports whether typ is an interface type.
73 func IsInterface(typ Type) bool {
74 _, ok := typ.Underlying().(*Interface)
78 // Comparable reports whether values of type T are comparable.
79 func Comparable(T Type) bool {
80 return comparable(T, nil)
83 func comparable(T Type, seen map[Type]bool) bool {
88 seen = make(map[Type]bool)
92 switch t := T.Underlying().(type) {
94 // assume invalid types to be comparable
95 // to avoid follow-up errors
96 return t.kind != UntypedNil
97 case *Pointer, *Interface, *Chan:
100 for _, f := range t.fields {
101 if !comparable(f.typ, seen) {
107 return comparable(t.elem, seen)
112 // hasNil reports whether a type includes the nil value.
113 func hasNil(typ Type) bool {
114 switch t := typ.Underlying().(type) {
116 return t.kind == UnsafePointer
117 case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
123 // identical reports whether x and y are identical types.
124 // Receivers of Signature types are ignored.
125 func (check *Checker) identical(x, y Type) bool {
126 return check.identical0(x, y, true, nil)
129 // identicalIgnoreTags reports whether x and y are identical types if tags are ignored.
130 // Receivers of Signature types are ignored.
131 func (check *Checker) identicalIgnoreTags(x, y Type) bool {
132 return check.identical0(x, y, false, nil)
135 // An ifacePair is a node in a stack of interface type pairs compared for identity.
136 type ifacePair struct {
141 func (p *ifacePair) identical(q *ifacePair) bool {
142 return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
145 func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool {
150 switch x := x.(type) {
152 // Basic types are singletons except for the rune and byte
153 // aliases, thus we cannot solely rely on the x == y check
154 // above. See also comment in TypeName.IsAlias.
155 if y, ok := y.(*Basic); ok {
156 return x.kind == y.kind
160 // Two array types are identical if they have identical element types
161 // and the same array length.
162 if y, ok := y.(*Array); ok {
163 // If one or both array lengths are unknown (< 0) due to some error,
164 // assume they are the same to avoid spurious follow-on errors.
165 return (x.len < 0 || y.len < 0 || x.len == y.len) && check.identical0(x.elem, y.elem, cmpTags, p)
169 // Two slice types are identical if they have identical element types.
170 if y, ok := y.(*Slice); ok {
171 return check.identical0(x.elem, y.elem, cmpTags, p)
175 // Two struct types are identical if they have the same sequence of fields,
176 // and if corresponding fields have the same names, and identical types,
177 // and identical tags. Two embedded fields are considered to have the same
178 // name. Lower-case field names from different packages are always different.
179 if y, ok := y.(*Struct); ok {
180 if x.NumFields() == y.NumFields() {
181 for i, f := range x.fields {
183 if f.embedded != g.embedded ||
184 cmpTags && x.Tag(i) != y.Tag(i) ||
185 !f.sameId(g.pkg, g.name) ||
186 !check.identical0(f.typ, g.typ, cmpTags, p) {
195 // Two pointer types are identical if they have identical base types.
196 if y, ok := y.(*Pointer); ok {
197 return check.identical0(x.base, y.base, cmpTags, p)
201 // Two tuples types are identical if they have the same number of elements
202 // and corresponding elements have identical types.
203 if y, ok := y.(*Tuple); ok {
204 if x.Len() == y.Len() {
206 for i, v := range x.vars {
208 if !check.identical0(v.typ, w.typ, cmpTags, p) {
218 // Two function types are identical if they have the same number of parameters
219 // and result values, corresponding parameter and result types are identical,
220 // and either both functions are variadic or neither is. Parameter and result
221 // names are not required to match.
222 if y, ok := y.(*Signature); ok {
223 return x.variadic == y.variadic &&
224 check.identical0(x.params, y.params, cmpTags, p) &&
225 check.identical0(x.results, y.results, cmpTags, p)
229 // Two interface types are identical if they have the same set of methods with
230 // the same names and identical function types. Lower-case method names from
231 // different packages are always different. The order of the methods is irrelevant.
232 if y, ok := y.(*Interface); ok {
233 // If identical0 is called (indirectly) via an external API entry point
234 // (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in
235 // that case, interfaces are expected to be complete and lazy completion
236 // here is not needed.
238 check.completeInterface(x)
239 check.completeInterface(y)
243 if len(a) == len(b) {
244 // Interface types are the only types where cycles can occur
245 // that are not "terminated" via named types; and such cycles
246 // can only be created via method parameter types that are
247 // anonymous interfaces (directly or indirectly) embedding
248 // the current interface. Example:
250 // type T interface {
254 // If two such (differently named) interfaces are compared,
255 // endless recursion occurs if the cycle is not detected.
257 // If x and y were compared before, they must be equal
258 // (if they were not, the recursion would have stopped);
259 // search the ifacePair stack for the same pair.
261 // This is a quadratic algorithm, but in practice these stacks
262 // are extremely short (bounded by the nesting depth of interface
263 // type declarations that recur via parameter types, an extremely
264 // rare occurrence). An alternative implementation might use a
265 // "visited" map, but that is probably less efficient overall.
266 q := &ifacePair{x, y, p}
269 return true // same pair was compared before
274 assertSortedMethods(a)
275 assertSortedMethods(b)
277 for i, f := range a {
279 if f.Id() != g.Id() || !check.identical0(f.typ, g.typ, cmpTags, q) {
288 // Two map types are identical if they have identical key and value types.
289 if y, ok := y.(*Map); ok {
290 return check.identical0(x.key, y.key, cmpTags, p) && check.identical0(x.elem, y.elem, cmpTags, p)
294 // Two channel types are identical if they have identical value types
295 // and the same direction.
296 if y, ok := y.(*Chan); ok {
297 return x.dir == y.dir && check.identical0(x.elem, y.elem, cmpTags, p)
301 // Two named types are identical if their type names originate
302 // in the same type declaration.
303 if y, ok := y.(*Named); ok {
304 return x.obj == y.obj
316 // Default returns the default "typed" type for an "untyped" type;
317 // it returns the incoming type for all other types. The default type
318 // for untyped nil is untyped nil.
320 func Default(typ Type) Type {
321 if t, ok := typ.(*Basic); ok {
328 return universeRune // use 'rune' name
332 return Typ[Complex128]