]> Cypherpunks.ru repositories - gostls13.git/blob - src/go/types/predicates.go
go/types: revert "no 'declared but not used' errors for invalid var decls"
[gostls13.git] / src / go / types / predicates.go
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 func isNamed(typ Type) bool {
10         if _, ok := typ.(*Basic); ok {
11                 return ok
12         }
13         _, ok := typ.(*Named)
14         return ok
15 }
16
17 func isBoolean(typ Type) bool {
18         t, ok := typ.Underlying().(*Basic)
19         return ok && t.info&IsBoolean != 0
20 }
21
22 func isInteger(typ Type) bool {
23         t, ok := typ.Underlying().(*Basic)
24         return ok && t.info&IsInteger != 0
25 }
26
27 func isUnsigned(typ Type) bool {
28         t, ok := typ.Underlying().(*Basic)
29         return ok && t.info&IsUnsigned != 0
30 }
31
32 func isFloat(typ Type) bool {
33         t, ok := typ.Underlying().(*Basic)
34         return ok && t.info&IsFloat != 0
35 }
36
37 func isComplex(typ Type) bool {
38         t, ok := typ.Underlying().(*Basic)
39         return ok && t.info&IsComplex != 0
40 }
41
42 func isNumeric(typ Type) bool {
43         t, ok := typ.Underlying().(*Basic)
44         return ok && t.info&IsNumeric != 0
45 }
46
47 func isString(typ Type) bool {
48         t, ok := typ.Underlying().(*Basic)
49         return ok && t.info&IsString != 0
50 }
51
52 func isTyped(typ Type) bool {
53         t, ok := typ.Underlying().(*Basic)
54         return !ok || t.info&IsUntyped == 0
55 }
56
57 func isUntyped(typ Type) bool {
58         t, ok := typ.Underlying().(*Basic)
59         return ok && t.info&IsUntyped != 0
60 }
61
62 func isOrdered(typ Type) bool {
63         t, ok := typ.Underlying().(*Basic)
64         return ok && t.info&IsOrdered != 0
65 }
66
67 func isConstType(typ Type) bool {
68         t, ok := typ.Underlying().(*Basic)
69         return ok && t.info&IsConstType != 0
70 }
71
72 // IsInterface reports whether typ is an interface type.
73 func IsInterface(typ Type) bool {
74         _, ok := typ.Underlying().(*Interface)
75         return ok
76 }
77
78 // Comparable reports whether values of type T are comparable.
79 func Comparable(T Type) bool {
80         return comparable(T, nil)
81 }
82
83 func comparable(T Type, seen map[Type]bool) bool {
84         if seen[T] {
85                 return true
86         }
87         if seen == nil {
88                 seen = make(map[Type]bool)
89         }
90         seen[T] = true
91
92         switch t := T.Underlying().(type) {
93         case *Basic:
94                 // assume invalid types to be comparable
95                 // to avoid follow-up errors
96                 return t.kind != UntypedNil
97         case *Pointer, *Interface, *Chan:
98                 return true
99         case *Struct:
100                 for _, f := range t.fields {
101                         if !comparable(f.typ, seen) {
102                                 return false
103                         }
104                 }
105                 return true
106         case *Array:
107                 return comparable(t.elem, seen)
108         }
109         return false
110 }
111
112 // hasNil reports whether a type includes the nil value.
113 func hasNil(typ Type) bool {
114         switch t := typ.Underlying().(type) {
115         case *Basic:
116                 return t.kind == UnsafePointer
117         case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
118                 return true
119         }
120         return false
121 }
122
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)
127 }
128
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)
133 }
134
135 // An ifacePair is a node in a stack of interface type pairs compared for identity.
136 type ifacePair struct {
137         x, y *Interface
138         prev *ifacePair
139 }
140
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
143 }
144
145 func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool {
146         if x == y {
147                 return true
148         }
149
150         switch x := x.(type) {
151         case *Basic:
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
157                 }
158
159         case *Array:
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)
166                 }
167
168         case *Slice:
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)
172                 }
173
174         case *Struct:
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 {
182                                         g := y.fields[i]
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) {
187                                                 return false
188                                         }
189                                 }
190                                 return true
191                         }
192                 }
193
194         case *Pointer:
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)
198                 }
199
200         case *Tuple:
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() {
205                                 if x != nil {
206                                         for i, v := range x.vars {
207                                                 w := y.vars[i]
208                                                 if !check.identical0(v.typ, w.typ, cmpTags, p) {
209                                                         return false
210                                                 }
211                                         }
212                                 }
213                                 return true
214                         }
215                 }
216
217         case *Signature:
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)
226                 }
227
228         case *Interface:
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.
237                         if check != nil {
238                                 check.completeInterface(x)
239                                 check.completeInterface(y)
240                         }
241                         a := x.allMethods
242                         b := y.allMethods
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:
249                                 //
250                                 //    type T interface {
251                                 //        m() interface{T}
252                                 //    }
253                                 //
254                                 // If two such (differently named) interfaces are compared,
255                                 // endless recursion occurs if the cycle is not detected.
256                                 //
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.
260                                 //
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}
267                                 for p != nil {
268                                         if p.identical(q) {
269                                                 return true // same pair was compared before
270                                         }
271                                         p = p.prev
272                                 }
273                                 if debug {
274                                         assertSortedMethods(a)
275                                         assertSortedMethods(b)
276                                 }
277                                 for i, f := range a {
278                                         g := b[i]
279                                         if f.Id() != g.Id() || !check.identical0(f.typ, g.typ, cmpTags, q) {
280                                                 return false
281                                         }
282                                 }
283                                 return true
284                         }
285                 }
286
287         case *Map:
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)
291                 }
292
293         case *Chan:
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)
298                 }
299
300         case *Named:
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
305                 }
306
307         case nil:
308
309         default:
310                 unreachable()
311         }
312
313         return false
314 }
315
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.
319 //
320 func Default(typ Type) Type {
321         if t, ok := typ.(*Basic); ok {
322                 switch t.kind {
323                 case UntypedBool:
324                         return Typ[Bool]
325                 case UntypedInt:
326                         return Typ[Int]
327                 case UntypedRune:
328                         return universeRune // use 'rune' name
329                 case UntypedFloat:
330                         return Typ[Float64]
331                 case UntypedComplex:
332                         return Typ[Complex128]
333                 case UntypedString:
334                         return Typ[String]
335                 }
336         }
337         return typ
338 }