]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/types2/unify.go
cmd/compile/internal/types2: when type hashing, use placeholders for type parameters
[gostls13.git] / src / cmd / compile / internal / types2 / unify.go
1 // Copyright 2020 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 type unification.
6
7 package types2
8
9 import (
10         "bytes"
11         "fmt"
12         "internal/buildcfg"
13 )
14
15 // The unifier maintains two separate sets of type parameters x and y
16 // which are used to resolve type parameters in the x and y arguments
17 // provided to the unify call. For unidirectional unification, only
18 // one of these sets (say x) is provided, and then type parameters are
19 // only resolved for the x argument passed to unify, not the y argument
20 // (even if that also contains possibly the same type parameters). This
21 // is crucial to infer the type parameters of self-recursive calls:
22 //
23 //      func f[P any](a P) { f(a) }
24 //
25 // For the call f(a) we want to infer that the type argument for P is P.
26 // During unification, the parameter type P must be resolved to the type
27 // parameter P ("x" side), but the argument type P must be left alone so
28 // that unification resolves the type parameter P to P.
29 //
30 // For bidirection unification, both sets are provided. This enables
31 // unification to go from argument to parameter type and vice versa.
32 // For constraint type inference, we use bidirectional unification
33 // where both the x and y type parameters are identical. This is done
34 // by setting up one of them (using init) and then assigning its value
35 // to the other.
36
37 // A unifier maintains the current type parameters for x and y
38 // and the respective types inferred for each type parameter.
39 // A unifier is created by calling newUnifier.
40 type unifier struct {
41         exact bool
42         x, y  tparamsList // x and y must initialized via tparamsList.init
43         types []Type      // inferred types, shared by x and y
44 }
45
46 // newUnifier returns a new unifier.
47 // If exact is set, unification requires unified types to match
48 // exactly. If exact is not set, a named type's underlying type
49 // is considered if unification would fail otherwise, and the
50 // direction of channels is ignored.
51 func newUnifier(exact bool) *unifier {
52         u := &unifier{exact: exact}
53         u.x.unifier = u
54         u.y.unifier = u
55         return u
56 }
57
58 // unify attempts to unify x and y and reports whether it succeeded.
59 func (u *unifier) unify(x, y Type) bool {
60         return u.nify(x, y, nil)
61 }
62
63 // A tparamsList describes a list of type parameters and the types inferred for them.
64 type tparamsList struct {
65         unifier *unifier
66         tparams []*TypeParam
67         // For each tparams element, there is a corresponding type slot index in indices.
68         // index  < 0: unifier.types[-index-1] == nil
69         // index == 0: no type slot allocated yet
70         // index  > 0: unifier.types[index-1] == typ
71         // Joined tparams elements share the same type slot and thus have the same index.
72         // By using a negative index for nil types we don't need to check unifier.types
73         // to see if we have a type or not.
74         indices []int // len(d.indices) == len(d.tparams)
75 }
76
77 // String returns a string representation for a tparamsList. For debugging.
78 func (d *tparamsList) String() string {
79         var buf bytes.Buffer
80         w := newTypeWriter(&buf, nil)
81         w.byte('[')
82         for i, tpar := range d.tparams {
83                 if i > 0 {
84                         w.string(", ")
85                 }
86                 w.typ(tpar)
87                 w.string(": ")
88                 w.typ(d.at(i))
89         }
90         w.byte(']')
91         return buf.String()
92 }
93
94 // init initializes d with the given type parameters.
95 // The type parameters must be in the order in which they appear in their declaration
96 // (this ensures that the tparams indices match the respective type parameter index).
97 func (d *tparamsList) init(tparams []*TypeParam) {
98         if len(tparams) == 0 {
99                 return
100         }
101         if debug {
102                 for i, tpar := range tparams {
103                         assert(i == tpar.index)
104                 }
105         }
106         d.tparams = tparams
107         d.indices = make([]int, len(tparams))
108 }
109
110 // join unifies the i'th type parameter of x with the j'th type parameter of y.
111 // If both type parameters already have a type associated with them and they are
112 // not joined, join fails and returns false.
113 func (u *unifier) join(i, j int) bool {
114         ti := u.x.indices[i]
115         tj := u.y.indices[j]
116         switch {
117         case ti == 0 && tj == 0:
118                 // Neither type parameter has a type slot associated with them.
119                 // Allocate a new joined nil type slot (negative index).
120                 u.types = append(u.types, nil)
121                 u.x.indices[i] = -len(u.types)
122                 u.y.indices[j] = -len(u.types)
123         case ti == 0:
124                 // The type parameter for x has no type slot yet. Use slot of y.
125                 u.x.indices[i] = tj
126         case tj == 0:
127                 // The type parameter for y has no type slot yet. Use slot of x.
128                 u.y.indices[j] = ti
129
130         // Both type parameters have a slot: ti != 0 && tj != 0.
131         case ti == tj:
132                 // Both type parameters already share the same slot. Nothing to do.
133                 break
134         case ti > 0 && tj > 0:
135                 // Both type parameters have (possibly different) inferred types. Cannot join.
136                 // TODO(gri) Should we check if types are identical? Investigate.
137                 return false
138         case ti > 0:
139                 // Only the type parameter for x has an inferred type. Use x slot for y.
140                 u.y.setIndex(j, ti)
141         // This case is handled like the default case.
142         // case tj > 0:
143         //      // Only the type parameter for y has an inferred type. Use y slot for x.
144         //      u.x.setIndex(i, tj)
145         default:
146                 // Neither type parameter has an inferred type. Use y slot for x
147                 // (or x slot for y, it doesn't matter).
148                 u.x.setIndex(i, tj)
149         }
150         return true
151 }
152
153 // If typ is a type parameter of d, index returns the type parameter index.
154 // Otherwise, the result is < 0.
155 func (d *tparamsList) index(typ Type) int {
156         if tpar, ok := typ.(*TypeParam); ok {
157                 return tparamIndex(d.tparams, tpar)
158         }
159         return -1
160 }
161
162 // If tpar is a type parameter in list, tparamIndex returns the type parameter index.
163 // Otherwise, the result is < 0. tpar must not be nil.
164 func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
165         // Temporary work-around for getting around a crash
166         // with unified build.
167         // TODO(gri) investigate and implement proper fix
168         if buildcfg.Experiment.Unified && tpar.index < 0 {
169                 return -1
170         }
171         if i := tpar.index; i < len(list) && list[i] == tpar {
172                 return i
173         }
174         return -1
175 }
176
177 // setIndex sets the type slot index for the i'th type parameter
178 // (and all its joined parameters) to tj. The type parameter
179 // must have a (possibly nil) type slot associated with it.
180 func (d *tparamsList) setIndex(i, tj int) {
181         ti := d.indices[i]
182         assert(ti != 0 && tj != 0)
183         for k, tk := range d.indices {
184                 if tk == ti {
185                         d.indices[k] = tj
186                 }
187         }
188 }
189
190 // at returns the type set for the i'th type parameter; or nil.
191 func (d *tparamsList) at(i int) Type {
192         if ti := d.indices[i]; ti > 0 {
193                 return d.unifier.types[ti-1]
194         }
195         return nil
196 }
197
198 // set sets the type typ for the i'th type parameter;
199 // typ must not be nil and it must not have been set before.
200 func (d *tparamsList) set(i int, typ Type) {
201         assert(typ != nil)
202         u := d.unifier
203         switch ti := d.indices[i]; {
204         case ti < 0:
205                 u.types[-ti-1] = typ
206                 d.setIndex(i, -ti)
207         case ti == 0:
208                 u.types = append(u.types, typ)
209                 d.indices[i] = len(u.types)
210         default:
211                 panic("type already set")
212         }
213 }
214
215 // types returns the list of inferred types (via unification) for the type parameters
216 // described by d, and an index. If all types were inferred, the returned index is < 0.
217 // Otherwise, it is the index of the first type parameter which couldn't be inferred;
218 // i.e., for which list[index] is nil.
219 func (d *tparamsList) types() (list []Type, index int) {
220         list = make([]Type, len(d.tparams))
221         index = -1
222         for i := range d.tparams {
223                 t := d.at(i)
224                 list[i] = t
225                 if index < 0 && t == nil {
226                         index = i
227                 }
228         }
229         return
230 }
231
232 func (u *unifier) nifyEq(x, y Type, p *ifacePair) bool {
233         return x == y || u.nify(x, y, p)
234 }
235
236 // nify implements the core unification algorithm which is an
237 // adapted version of Checker.identical. For changes to that
238 // code the corresponding changes should be made here.
239 // Must not be called directly from outside the unifier.
240 func (u *unifier) nify(x, y Type, p *ifacePair) bool {
241         if !u.exact {
242                 // If exact unification is known to fail because we attempt to
243                 // match a type name against an unnamed type literal, consider
244                 // the underlying type of the named type.
245                 // (We use !hasName to exclude any type with a name, including
246                 // basic types and type parameters; the rest are unamed types.)
247                 if nx, _ := x.(*Named); nx != nil && !hasName(y) {
248                         return u.nify(nx.under(), y, p)
249                 } else if ny, _ := y.(*Named); ny != nil && !hasName(x) {
250                         return u.nify(x, ny.under(), p)
251                 }
252         }
253
254         // Cases where at least one of x or y is a type parameter.
255         switch i, j := u.x.index(x), u.y.index(y); {
256         case i >= 0 && j >= 0:
257                 // both x and y are type parameters
258                 if u.join(i, j) {
259                         return true
260                 }
261                 // both x and y have an inferred type - they must match
262                 return u.nifyEq(u.x.at(i), u.y.at(j), p)
263
264         case i >= 0:
265                 // x is a type parameter, y is not
266                 if tx := u.x.at(i); tx != nil {
267                         return u.nifyEq(tx, y, p)
268                 }
269                 // otherwise, infer type from y
270                 u.x.set(i, y)
271                 return true
272
273         case j >= 0:
274                 // y is a type parameter, x is not
275                 if ty := u.y.at(j); ty != nil {
276                         return u.nifyEq(x, ty, p)
277                 }
278                 // otherwise, infer type from x
279                 u.y.set(j, x)
280                 return true
281         }
282
283         // For type unification, do not shortcut (x == y) for identical
284         // types. Instead keep comparing them element-wise to unify the
285         // matching (and equal type parameter types). A simple test case
286         // where this matters is: func f[P any](a P) { f(a) } .
287
288         switch x := x.(type) {
289         case *Basic:
290                 // Basic types are singletons except for the rune and byte
291                 // aliases, thus we cannot solely rely on the x == y check
292                 // above. See also comment in TypeName.IsAlias.
293                 if y, ok := y.(*Basic); ok {
294                         return x.kind == y.kind
295                 }
296
297         case *Array:
298                 // Two array types are identical if they have identical element types
299                 // and the same array length.
300                 if y, ok := y.(*Array); ok {
301                         // If one or both array lengths are unknown (< 0) due to some error,
302                         // assume they are the same to avoid spurious follow-on errors.
303                         return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, p)
304                 }
305
306         case *Slice:
307                 // Two slice types are identical if they have identical element types.
308                 if y, ok := y.(*Slice); ok {
309                         return u.nify(x.elem, y.elem, p)
310                 }
311
312         case *Struct:
313                 // Two struct types are identical if they have the same sequence of fields,
314                 // and if corresponding fields have the same names, and identical types,
315                 // and identical tags. Two embedded fields are considered to have the same
316                 // name. Lower-case field names from different packages are always different.
317                 if y, ok := y.(*Struct); ok {
318                         if x.NumFields() == y.NumFields() {
319                                 for i, f := range x.fields {
320                                         g := y.fields[i]
321                                         if f.embedded != g.embedded ||
322                                                 x.Tag(i) != y.Tag(i) ||
323                                                 !f.sameId(g.pkg, g.name) ||
324                                                 !u.nify(f.typ, g.typ, p) {
325                                                 return false
326                                         }
327                                 }
328                                 return true
329                         }
330                 }
331
332         case *Pointer:
333                 // Two pointer types are identical if they have identical base types.
334                 if y, ok := y.(*Pointer); ok {
335                         return u.nify(x.base, y.base, p)
336                 }
337
338         case *Tuple:
339                 // Two tuples types are identical if they have the same number of elements
340                 // and corresponding elements have identical types.
341                 if y, ok := y.(*Tuple); ok {
342                         if x.Len() == y.Len() {
343                                 if x != nil {
344                                         for i, v := range x.vars {
345                                                 w := y.vars[i]
346                                                 if !u.nify(v.typ, w.typ, p) {
347                                                         return false
348                                                 }
349                                         }
350                                 }
351                                 return true
352                         }
353                 }
354
355         case *Signature:
356                 // Two function types are identical if they have the same number of parameters
357                 // and result values, corresponding parameter and result types are identical,
358                 // and either both functions are variadic or neither is. Parameter and result
359                 // names are not required to match.
360                 // TODO(gri) handle type parameters or document why we can ignore them.
361                 if y, ok := y.(*Signature); ok {
362                         return x.variadic == y.variadic &&
363                                 u.nify(x.params, y.params, p) &&
364                                 u.nify(x.results, y.results, p)
365                 }
366
367         case *Interface:
368                 // Two interface types are identical if they have the same set of methods with
369                 // the same names and identical function types. Lower-case method names from
370                 // different packages are always different. The order of the methods is irrelevant.
371                 if y, ok := y.(*Interface); ok {
372                         xset := x.typeSet()
373                         yset := y.typeSet()
374                         if !xset.terms.equal(yset.terms) {
375                                 return false
376                         }
377                         a := xset.methods
378                         b := yset.methods
379                         if len(a) == len(b) {
380                                 // Interface types are the only types where cycles can occur
381                                 // that are not "terminated" via named types; and such cycles
382                                 // can only be created via method parameter types that are
383                                 // anonymous interfaces (directly or indirectly) embedding
384                                 // the current interface. Example:
385                                 //
386                                 //    type T interface {
387                                 //        m() interface{T}
388                                 //    }
389                                 //
390                                 // If two such (differently named) interfaces are compared,
391                                 // endless recursion occurs if the cycle is not detected.
392                                 //
393                                 // If x and y were compared before, they must be equal
394                                 // (if they were not, the recursion would have stopped);
395                                 // search the ifacePair stack for the same pair.
396                                 //
397                                 // This is a quadratic algorithm, but in practice these stacks
398                                 // are extremely short (bounded by the nesting depth of interface
399                                 // type declarations that recur via parameter types, an extremely
400                                 // rare occurrence). An alternative implementation might use a
401                                 // "visited" map, but that is probably less efficient overall.
402                                 q := &ifacePair{x, y, p}
403                                 for p != nil {
404                                         if p.identical(q) {
405                                                 return true // same pair was compared before
406                                         }
407                                         p = p.prev
408                                 }
409                                 if debug {
410                                         assertSortedMethods(a)
411                                         assertSortedMethods(b)
412                                 }
413                                 for i, f := range a {
414                                         g := b[i]
415                                         if f.Id() != g.Id() || !u.nify(f.typ, g.typ, q) {
416                                                 return false
417                                         }
418                                 }
419                                 return true
420                         }
421                 }
422
423         case *Map:
424                 // Two map types are identical if they have identical key and value types.
425                 if y, ok := y.(*Map); ok {
426                         return u.nify(x.key, y.key, p) && u.nify(x.elem, y.elem, p)
427                 }
428
429         case *Chan:
430                 // Two channel types are identical if they have identical value types.
431                 if y, ok := y.(*Chan); ok {
432                         return (!u.exact || x.dir == y.dir) && u.nify(x.elem, y.elem, p)
433                 }
434
435         case *Named:
436                 // TODO(gri) This code differs now from the parallel code in Checker.identical. Investigate.
437                 if y, ok := y.(*Named); ok {
438                         xargs := x.targs.list()
439                         yargs := y.targs.list()
440
441                         // TODO(gri) This is not always correct: two types may have the same names
442                         //           in the same package if one of them is nested in a function.
443                         //           Extremely unlikely but we need an always correct solution.
444                         if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
445                                 assert(len(xargs) == len(yargs))
446                                 for i, x := range xargs {
447                                         if !u.nify(x, yargs[i], p) {
448                                                 return false
449                                         }
450                                 }
451                                 return true
452                         }
453                 }
454
455         case *TypeParam:
456                 // Two type parameters (which are not part of the type parameters of the
457                 // enclosing type as those are handled in the beginning of this function)
458                 // are identical if they originate in the same declaration.
459                 return x == y
460
461         case nil:
462                 // avoid a crash in case of nil type
463
464         default:
465                 panic(fmt.Sprintf("### u.nify(%s, %s), u.x.tparams = %s", x, y, u.x.tparams))
466         }
467
468         return false
469 }