]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/typecheck/subr.go
9760e366b59ada709ec954de760ef953c9833c54
[gostls13.git] / src / cmd / compile / internal / typecheck / subr.go
1 // Copyright 2009 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 package typecheck
6
7 import (
8         "bytes"
9         "fmt"
10         "sort"
11         "strings"
12
13         "cmd/compile/internal/base"
14         "cmd/compile/internal/ir"
15         "cmd/compile/internal/types"
16         "cmd/internal/obj"
17         "cmd/internal/objabi"
18         "cmd/internal/src"
19 )
20
21 func AssignConv(n ir.Node, t *types.Type, context string) ir.Node {
22         return assignconvfn(n, t, func() string { return context })
23 }
24
25 // LookupNum returns types.LocalPkg.LookupNum(prefix, n).
26 func LookupNum(prefix string, n int) *types.Sym {
27         return types.LocalPkg.LookupNum(prefix, n)
28 }
29
30 // Given funarg struct list, return list of fn args.
31 func NewFuncParams(tl *types.Type, mustname bool) []*ir.Field {
32         var args []*ir.Field
33         gen := 0
34         for _, t := range tl.Fields().Slice() {
35                 s := t.Sym
36                 if mustname && (s == nil || s.Name == "_") {
37                         // invent a name so that we can refer to it in the trampoline
38                         s = LookupNum(".anon", gen)
39                         gen++
40                 } else if s != nil && s.Pkg != types.LocalPkg {
41                         // TODO(mdempsky): Preserve original position, name, and package.
42                         s = Lookup(s.Name)
43                 }
44                 a := ir.NewField(base.Pos, s, t.Type)
45                 a.Pos = t.Pos
46                 a.IsDDD = t.IsDDD()
47                 args = append(args, a)
48         }
49
50         return args
51 }
52
53 // NewName returns a new ONAME Node associated with symbol s.
54 func NewName(s *types.Sym) *ir.Name {
55         n := ir.NewNameAt(base.Pos, s)
56         n.Curfn = ir.CurFunc
57         return n
58 }
59
60 // NodAddr returns a node representing &n at base.Pos.
61 func NodAddr(n ir.Node) *ir.AddrExpr {
62         return NodAddrAt(base.Pos, n)
63 }
64
65 // NodAddrAt returns a node representing &n at position pos.
66 func NodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
67         n = markAddrOf(n)
68         return ir.NewAddrExpr(pos, n)
69 }
70
71 func markAddrOf(n ir.Node) ir.Node {
72         if IncrementalAddrtaken {
73                 // We can only do incremental addrtaken computation when it is ok
74                 // to typecheck the argument of the OADDR. That's only safe after the
75                 // main typecheck has completed, and not loading the inlined body.
76                 // The argument to OADDR needs to be typechecked because &x[i] takes
77                 // the address of x if x is an array, but not if x is a slice.
78                 // Note: OuterValue doesn't work correctly until n is typechecked.
79                 n = typecheck(n, ctxExpr)
80                 if x := ir.OuterValue(n); x.Op() == ir.ONAME {
81                         x.Name().SetAddrtaken(true)
82                 }
83         } else {
84                 // Remember that we built an OADDR without computing the Addrtaken bit for
85                 // its argument. We'll do that later in bulk using computeAddrtaken.
86                 DirtyAddrtaken = true
87         }
88         return n
89 }
90
91 // If IncrementalAddrtaken is false, we do not compute Addrtaken for an OADDR Node
92 // when it is built. The Addrtaken bits are set in bulk by computeAddrtaken.
93 // If IncrementalAddrtaken is true, then when an OADDR Node is built the Addrtaken
94 // field of its argument is updated immediately.
95 var IncrementalAddrtaken = false
96
97 // If DirtyAddrtaken is true, then there are OADDR whose corresponding arguments
98 // have not yet been marked as Addrtaken.
99 var DirtyAddrtaken = false
100
101 func ComputeAddrtaken(top []ir.Node) {
102         for _, n := range top {
103                 var doVisit func(n ir.Node)
104                 doVisit = func(n ir.Node) {
105                         if n.Op() == ir.OADDR {
106                                 if x := ir.OuterValue(n.(*ir.AddrExpr).X); x.Op() == ir.ONAME {
107                                         x.Name().SetAddrtaken(true)
108                                         if x.Name().IsClosureVar() {
109                                                 // Mark the original variable as Addrtaken so that capturevars
110                                                 // knows not to pass it by value.
111                                                 x.Name().Defn.Name().SetAddrtaken(true)
112                                         }
113                                 }
114                         }
115                         if n.Op() == ir.OCLOSURE {
116                                 ir.VisitList(n.(*ir.ClosureExpr).Func.Body, doVisit)
117                         }
118                 }
119                 ir.Visit(n, doVisit)
120         }
121 }
122
123 // LinksymAddr returns a new expression that evaluates to the address
124 // of lsym. typ specifies the type of the addressed memory.
125 func LinksymAddr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *ir.AddrExpr {
126         n := ir.NewLinksymExpr(pos, lsym, typ)
127         return Expr(NodAddrAt(pos, n)).(*ir.AddrExpr)
128 }
129
130 func NodNil() ir.Node {
131         n := ir.NewNilExpr(base.Pos)
132         n.SetType(types.Types[types.TNIL])
133         return n
134 }
135
136 // AddImplicitDots finds missing fields in obj.field that
137 // will give the shortest unique addressing and
138 // modifies the tree with missing field names.
139 func AddImplicitDots(n *ir.SelectorExpr) *ir.SelectorExpr {
140         n.X = typecheck(n.X, ctxType|ctxExpr)
141         t := n.X.Type()
142         if t == nil {
143                 return n
144         }
145
146         if n.X.Op() == ir.OTYPE {
147                 return n
148         }
149
150         s := n.Sel
151         if s == nil {
152                 return n
153         }
154
155         switch path, ambig := dotpath(s, t, nil, false); {
156         case path != nil:
157                 // rebuild elided dots
158                 for c := len(path) - 1; c >= 0; c-- {
159                         dot := ir.NewSelectorExpr(n.Pos(), ir.ODOT, n.X, path[c].field.Sym)
160                         dot.SetImplicit(true)
161                         dot.SetType(path[c].field.Type)
162                         n.X = dot
163                 }
164         case ambig:
165                 base.Errorf("ambiguous selector %v", n)
166                 n.X = nil
167         }
168
169         return n
170 }
171
172 // CalcMethods calculates all the methods (including embedding) of a non-interface
173 // type t.
174 func CalcMethods(t *types.Type) {
175         if t == nil || t.AllMethods().Len() != 0 {
176                 return
177         }
178
179         // mark top-level method symbols
180         // so that expand1 doesn't consider them.
181         for _, f := range t.Methods().Slice() {
182                 f.Sym.SetUniq(true)
183         }
184
185         // generate all reachable methods
186         slist = slist[:0]
187         expand1(t, true)
188
189         // check each method to be uniquely reachable
190         var ms []*types.Field
191         for i, sl := range slist {
192                 slist[i].field = nil
193                 sl.field.Sym.SetUniq(false)
194
195                 var f *types.Field
196                 path, _ := dotpath(sl.field.Sym, t, &f, false)
197                 if path == nil {
198                         continue
199                 }
200
201                 // dotpath may have dug out arbitrary fields, we only want methods.
202                 if !f.IsMethod() {
203                         continue
204                 }
205
206                 // add it to the base type method list
207                 f = f.Copy()
208                 f.Embedded = 1 // needs a trampoline
209                 for _, d := range path {
210                         if d.field.Type.IsPtr() {
211                                 f.Embedded = 2
212                                 break
213                         }
214                 }
215                 ms = append(ms, f)
216         }
217
218         for _, f := range t.Methods().Slice() {
219                 f.Sym.SetUniq(false)
220         }
221
222         ms = append(ms, t.Methods().Slice()...)
223         sort.Sort(types.MethodsByName(ms))
224         t.SetAllMethods(ms)
225 }
226
227 // adddot1 returns the number of fields or methods named s at depth d in Type t.
228 // If exactly one exists, it will be returned in *save (if save is not nil),
229 // and dotlist will contain the path of embedded fields traversed to find it,
230 // in reverse order. If none exist, more will indicate whether t contains any
231 // embedded fields at depth d, so callers can decide whether to retry at
232 // a greater depth.
233 func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) {
234         if t.Recur() {
235                 return
236         }
237         t.SetRecur(true)
238         defer t.SetRecur(false)
239
240         var u *types.Type
241         d--
242         if d < 0 {
243                 // We've reached our target depth. If t has any fields/methods
244                 // named s, then we're done. Otherwise, we still need to check
245                 // below for embedded fields.
246                 c = lookdot0(s, t, save, ignorecase)
247                 if c != 0 {
248                         return c, false
249                 }
250         }
251
252         u = t
253         if u.IsPtr() {
254                 u = u.Elem()
255         }
256         if !u.IsStruct() && !u.IsInterface() {
257                 return c, false
258         }
259
260         var fields *types.Fields
261         if u.IsStruct() {
262                 fields = u.Fields()
263         } else {
264                 fields = u.AllMethods()
265         }
266         for _, f := range fields.Slice() {
267                 if f.Embedded == 0 || f.Sym == nil {
268                         continue
269                 }
270                 if d < 0 {
271                         // Found an embedded field at target depth.
272                         return c, true
273                 }
274                 a, more1 := adddot1(s, f.Type, d, save, ignorecase)
275                 if a != 0 && c == 0 {
276                         dotlist[d].field = f
277                 }
278                 c += a
279                 if more1 {
280                         more = true
281                 }
282         }
283
284         return c, more
285 }
286
287 // dotlist is used by adddot1 to record the path of embedded fields
288 // used to access a target field or method.
289 // Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
290 var dotlist = make([]dlist, 10)
291
292 // Convert node n for assignment to type t.
293 func assignconvfn(n ir.Node, t *types.Type, context func() string) ir.Node {
294         if n == nil || n.Type() == nil {
295                 return n
296         }
297
298         if t.Kind() == types.TBLANK && n.Type().Kind() == types.TNIL {
299                 base.Errorf("use of untyped nil")
300         }
301
302         n = convlit1(n, t, false, context)
303         if n.Type() == nil {
304                 base.Fatalf("cannot assign %v to %v", n, t)
305         }
306         if n.Type().IsUntyped() {
307                 base.Fatalf("%L has untyped type", n)
308         }
309         if t.Kind() == types.TBLANK {
310                 return n
311         }
312         if types.Identical(n.Type(), t) {
313                 return n
314         }
315
316         op, why := Assignop(n.Type(), t)
317         if op == ir.OXXX {
318                 base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
319                 op = ir.OCONV
320         }
321
322         r := ir.NewConvExpr(base.Pos, op, t, n)
323         r.SetTypecheck(1)
324         r.SetImplicit(true)
325         return r
326 }
327
328 // Is type src assignment compatible to type dst?
329 // If so, return op code to use in conversion.
330 // If not, return OXXX. In this case, the string return parameter may
331 // hold a reason why. In all other cases, it'll be the empty string.
332 func Assignop(src, dst *types.Type) (ir.Op, string) {
333         if src == dst {
334                 return ir.OCONVNOP, ""
335         }
336         if src == nil || dst == nil || src.Kind() == types.TFORW || dst.Kind() == types.TFORW || src.Underlying() == nil || dst.Underlying() == nil {
337                 return ir.OXXX, ""
338         }
339
340         // 1. src type is identical to dst.
341         if types.Identical(src, dst) {
342                 return ir.OCONVNOP, ""
343         }
344         return Assignop1(src, dst)
345 }
346
347 func Assignop1(src, dst *types.Type) (ir.Op, string) {
348         // 2. src and dst have identical underlying types and
349         //   a. either src or dst is not a named type, or
350         //   b. both are empty interface types, or
351         //   c. at least one is a gcshape type.
352         // For assignable but different non-empty interface types,
353         // we want to recompute the itab. Recomputing the itab ensures
354         // that itabs are unique (thus an interface with a compile-time
355         // type I has an itab with interface type I).
356         if types.Identical(src.Underlying(), dst.Underlying()) {
357                 if src.IsEmptyInterface() {
358                         // Conversion between two empty interfaces
359                         // requires no code.
360                         return ir.OCONVNOP, ""
361                 }
362                 if (src.Sym() == nil || dst.Sym() == nil) && !src.IsInterface() {
363                         // Conversion between two types, at least one unnamed,
364                         // needs no conversion. The exception is nonempty interfaces
365                         // which need to have their itab updated.
366                         return ir.OCONVNOP, ""
367                 }
368                 if src.IsShape() || dst.IsShape() {
369                         // Conversion between a shape type and one of the types
370                         // it represents also needs no conversion.
371                         return ir.OCONVNOP, ""
372                 }
373         }
374
375         // 3. dst is an interface type and src implements dst.
376         if dst.IsInterface() && src.Kind() != types.TNIL {
377                 var missing, have *types.Field
378                 var ptr int
379                 if src.IsShape() {
380                         // Shape types implement things they have already
381                         // been typechecked to implement, even if they
382                         // don't have the methods for them.
383                         return ir.OCONVIFACE, ""
384                 }
385                 if base.Debug.Unified != 0 && src.HasShape() {
386                         // Unified IR uses OCONVIFACE for converting all derived types
387                         // to interface type, not just type arguments themselves.
388                         return ir.OCONVIFACE, ""
389                 }
390                 if implements(src, dst, &missing, &have, &ptr) {
391                         return ir.OCONVIFACE, ""
392                 }
393
394                 var why string
395                 if isptrto(src, types.TINTER) {
396                         why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
397                 } else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
398                         why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
399                 } else if have != nil && have.Sym == missing.Sym {
400                         why = fmt.Sprintf(":\n\t%v does not implement %v %s", src, dst, wrongTypeFor(have.Sym, have.Type, missing.Sym, missing.Type))
401                 } else if ptr != 0 {
402                         why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
403                 } else if have != nil {
404                         why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+
405                                 "\t\thave %v%S\n\t\twant %v%S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
406                 } else {
407                         why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
408                 }
409
410                 return ir.OXXX, why
411         }
412
413         if isptrto(dst, types.TINTER) {
414                 why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
415                 return ir.OXXX, why
416         }
417
418         if src.IsInterface() && dst.Kind() != types.TBLANK {
419                 var missing, have *types.Field
420                 var ptr int
421                 var why string
422                 if implements(dst, src, &missing, &have, &ptr) {
423                         why = ": need type assertion"
424                 }
425                 return ir.OXXX, why
426         }
427
428         // 4. src is a bidirectional channel value, dst is a channel type,
429         // src and dst have identical element types, and
430         // either src or dst is not a named type.
431         if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
432                 if types.Identical(src.Elem(), dst.Elem()) && (src.Sym() == nil || dst.Sym() == nil) {
433                         return ir.OCONVNOP, ""
434                 }
435         }
436
437         // 5. src is the predeclared identifier nil and dst is a nillable type.
438         if src.Kind() == types.TNIL {
439                 switch dst.Kind() {
440                 case types.TPTR,
441                         types.TFUNC,
442                         types.TMAP,
443                         types.TCHAN,
444                         types.TINTER,
445                         types.TSLICE:
446                         return ir.OCONVNOP, ""
447                 }
448         }
449
450         // 6. rule about untyped constants - already converted by DefaultLit.
451
452         // 7. Any typed value can be assigned to the blank identifier.
453         if dst.Kind() == types.TBLANK {
454                 return ir.OCONVNOP, ""
455         }
456
457         return ir.OXXX, ""
458 }
459
460 // Can we convert a value of type src to a value of type dst?
461 // If so, return op code to use in conversion (maybe OCONVNOP).
462 // If not, return OXXX. In this case, the string return parameter may
463 // hold a reason why. In all other cases, it'll be the empty string.
464 // srcConstant indicates whether the value of type src is a constant.
465 func Convertop(srcConstant bool, src, dst *types.Type) (ir.Op, string) {
466         if src == dst {
467                 return ir.OCONVNOP, ""
468         }
469         if src == nil || dst == nil {
470                 return ir.OXXX, ""
471         }
472
473         // Conversions from regular to not-in-heap are not allowed
474         // (unless it's unsafe.Pointer). These are runtime-specific
475         // rules.
476         // (a) Disallow (*T) to (*U) where T is not-in-heap but U isn't.
477         if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
478                 why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
479                 return ir.OXXX, why
480         }
481         // (b) Disallow string to []T where T is not-in-heap.
482         if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Kind() == types.ByteType.Kind() || dst.Elem().Kind() == types.RuneType.Kind()) {
483                 why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
484                 return ir.OXXX, why
485         }
486
487         // 1. src can be assigned to dst.
488         op, why := Assignop(src, dst)
489         if op != ir.OXXX {
490                 return op, why
491         }
492
493         // The rules for interfaces are no different in conversions
494         // than assignments. If interfaces are involved, stop now
495         // with the good message from assignop.
496         // Otherwise clear the error.
497         if src.IsInterface() || dst.IsInterface() {
498                 return ir.OXXX, why
499         }
500
501         // 2. Ignoring struct tags, src and dst have identical underlying types.
502         if types.IdenticalIgnoreTags(src.Underlying(), dst.Underlying()) {
503                 return ir.OCONVNOP, ""
504         }
505
506         // 3. src and dst are unnamed pointer types and, ignoring struct tags,
507         // their base types have identical underlying types.
508         if src.IsPtr() && dst.IsPtr() && src.Sym() == nil && dst.Sym() == nil {
509                 if types.IdenticalIgnoreTags(src.Elem().Underlying(), dst.Elem().Underlying()) {
510                         return ir.OCONVNOP, ""
511                 }
512         }
513
514         // 4. src and dst are both integer or floating point types.
515         if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
516                 if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
517                         return ir.OCONVNOP, ""
518                 }
519                 return ir.OCONV, ""
520         }
521
522         // 5. src and dst are both complex types.
523         if src.IsComplex() && dst.IsComplex() {
524                 if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
525                         return ir.OCONVNOP, ""
526                 }
527                 return ir.OCONV, ""
528         }
529
530         // Special case for constant conversions: any numeric
531         // conversion is potentially okay. We'll validate further
532         // within evconst. See #38117.
533         if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
534                 return ir.OCONV, ""
535         }
536
537         // 6. src is an integer or has type []byte or []rune
538         // and dst is a string type.
539         if src.IsInteger() && dst.IsString() {
540                 return ir.ORUNESTR, ""
541         }
542
543         if src.IsSlice() && dst.IsString() {
544                 if src.Elem().Kind() == types.ByteType.Kind() {
545                         return ir.OBYTES2STR, ""
546                 }
547                 if src.Elem().Kind() == types.RuneType.Kind() {
548                         return ir.ORUNES2STR, ""
549                 }
550         }
551
552         // 7. src is a string and dst is []byte or []rune.
553         // String to slice.
554         if src.IsString() && dst.IsSlice() {
555                 if dst.Elem().Kind() == types.ByteType.Kind() {
556                         return ir.OSTR2BYTES, ""
557                 }
558                 if dst.Elem().Kind() == types.RuneType.Kind() {
559                         return ir.OSTR2RUNES, ""
560                 }
561         }
562
563         // 8. src is a pointer or uintptr and dst is unsafe.Pointer.
564         if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() {
565                 return ir.OCONVNOP, ""
566         }
567
568         // 9. src is unsafe.Pointer and dst is a pointer or uintptr.
569         if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
570                 return ir.OCONVNOP, ""
571         }
572
573         // 10. src is map and dst is a pointer to corresponding hmap.
574         // This rule is needed for the implementation detail that
575         // go gc maps are implemented as a pointer to a hmap struct.
576         if src.Kind() == types.TMAP && dst.IsPtr() &&
577                 src.MapType().Hmap == dst.Elem() {
578                 return ir.OCONVNOP, ""
579         }
580
581         // 11. src is a slice and dst is an array or pointer-to-array.
582         // They must have same element type.
583         if src.IsSlice() {
584                 if dst.IsArray() && types.Identical(src.Elem(), dst.Elem()) {
585                         return ir.OSLICE2ARR, ""
586                 }
587                 if dst.IsPtr() && dst.Elem().IsArray() &&
588                         types.Identical(src.Elem(), dst.Elem().Elem()) {
589                         return ir.OSLICE2ARRPTR, ""
590                 }
591         }
592
593         return ir.OXXX, ""
594 }
595
596 // Code to resolve elided DOTs in embedded types.
597
598 // A dlist stores a pointer to a TFIELD Type embedded within
599 // a TSTRUCT or TINTER Type.
600 type dlist struct {
601         field *types.Field
602 }
603
604 // dotpath computes the unique shortest explicit selector path to fully qualify
605 // a selection expression x.f, where x is of type t and f is the symbol s.
606 // If no such path exists, dotpath returns nil.
607 // If there are multiple shortest paths to the same depth, ambig is true.
608 func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []dlist, ambig bool) {
609         // The embedding of types within structs imposes a tree structure onto
610         // types: structs parent the types they embed, and types parent their
611         // fields or methods. Our goal here is to find the shortest path to
612         // a field or method named s in the subtree rooted at t. To accomplish
613         // that, we iteratively perform depth-first searches of increasing depth
614         // until we either find the named field/method or exhaust the tree.
615         for d := 0; ; d++ {
616                 if d > len(dotlist) {
617                         dotlist = append(dotlist, dlist{})
618                 }
619                 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
620                         return dotlist[:d], false
621                 } else if c > 1 {
622                         return nil, true
623                 } else if !more {
624                         return nil, false
625                 }
626         }
627 }
628
629 func expand0(t *types.Type) {
630         u := t
631         if u.IsPtr() {
632                 u = u.Elem()
633         }
634
635         if u.IsInterface() {
636                 for _, f := range u.AllMethods().Slice() {
637                         if f.Sym.Uniq() {
638                                 continue
639                         }
640                         f.Sym.SetUniq(true)
641                         slist = append(slist, symlink{field: f})
642                 }
643
644                 return
645         }
646
647         u = types.ReceiverBaseType(t)
648         if u != nil {
649                 for _, f := range u.Methods().Slice() {
650                         if f.Sym.Uniq() {
651                                 continue
652                         }
653                         f.Sym.SetUniq(true)
654                         slist = append(slist, symlink{field: f})
655                 }
656         }
657 }
658
659 func expand1(t *types.Type, top bool) {
660         if t.Recur() {
661                 return
662         }
663         t.SetRecur(true)
664
665         if !top {
666                 expand0(t)
667         }
668
669         u := t
670         if u.IsPtr() {
671                 u = u.Elem()
672         }
673
674         if u.IsStruct() || u.IsInterface() {
675                 var fields *types.Fields
676                 if u.IsStruct() {
677                         fields = u.Fields()
678                 } else {
679                         fields = u.AllMethods()
680                 }
681                 for _, f := range fields.Slice() {
682                         if f.Embedded == 0 {
683                                 continue
684                         }
685                         if f.Sym == nil {
686                                 continue
687                         }
688                         expand1(f.Type, false)
689                 }
690         }
691
692         t.SetRecur(false)
693 }
694
695 func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, followptr bool) {
696         if t == nil {
697                 return nil, false
698         }
699
700         path, ambig := dotpath(s, t, &m, ignorecase)
701         if path == nil {
702                 if ambig {
703                         base.Errorf("%v.%v is ambiguous", t, s)
704                 }
705                 return nil, false
706         }
707
708         for _, d := range path {
709                 if d.field.Type.IsPtr() {
710                         followptr = true
711                         break
712                 }
713         }
714
715         if !m.IsMethod() {
716                 base.Errorf("%v.%v is a field, not a method", t, s)
717                 return nil, followptr
718         }
719
720         return m, followptr
721 }
722
723 // implements reports whether t implements the interface iface. t can be
724 // an interface, a type parameter, or a concrete type. If implements returns
725 // false, it stores a method of iface that is not implemented in *m. If the
726 // method name matches but the type is wrong, it additionally stores the type
727 // of the method (on t) in *samename.
728 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
729         t0 := t
730         if t == nil {
731                 return false
732         }
733
734         if t.IsInterface() || t.IsTypeParam() {
735                 if t.IsTypeParam() {
736                         // If t is a simple type parameter T, its type and underlying is the same.
737                         // If t is a type definition:'type P[T any] T', its type is P[T] and its
738                         // underlying is T. Therefore we use 't.Underlying() != t' to distinguish them.
739                         if t.Underlying() != t {
740                                 CalcMethods(t)
741                         } else {
742                                 // A typeparam satisfies an interface if its type bound
743                                 // has all the methods of that interface.
744                                 t = t.Bound()
745                         }
746                 }
747                 i := 0
748                 tms := t.AllMethods().Slice()
749                 for _, im := range iface.AllMethods().Slice() {
750                         for i < len(tms) && tms[i].Sym != im.Sym {
751                                 i++
752                         }
753                         if i == len(tms) {
754                                 *m = im
755                                 *samename = nil
756                                 *ptr = 0
757                                 return false
758                         }
759                         tm := tms[i]
760                         if !types.Identical(tm.Type, im.Type) {
761                                 *m = im
762                                 *samename = tm
763                                 *ptr = 0
764                                 return false
765                         }
766                 }
767
768                 return true
769         }
770
771         t = types.ReceiverBaseType(t)
772         var tms []*types.Field
773         if t != nil {
774                 CalcMethods(t)
775                 tms = t.AllMethods().Slice()
776         }
777         i := 0
778         for _, im := range iface.AllMethods().Slice() {
779                 for i < len(tms) && tms[i].Sym != im.Sym {
780                         i++
781                 }
782                 if i == len(tms) {
783                         *m = im
784                         *samename, _ = ifacelookdot(im.Sym, t, true)
785                         *ptr = 0
786                         return false
787                 }
788                 tm := tms[i]
789                 if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
790                         *m = im
791                         *samename = tm
792                         *ptr = 0
793                         return false
794                 }
795                 followptr := tm.Embedded == 2
796
797                 // if pointer receiver in method,
798                 // the method does not exist for value types.
799                 rcvr := tm.Type.Recv().Type
800                 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !types.IsInterfaceMethod(tm.Type) {
801                         if false && base.Flag.LowerR != 0 {
802                                 base.Errorf("interface pointer mismatch")
803                         }
804
805                         *m = im
806                         *samename = nil
807                         *ptr = 1
808                         return false
809                 }
810         }
811
812         return true
813 }
814
815 func isptrto(t *types.Type, et types.Kind) bool {
816         if t == nil {
817                 return false
818         }
819         if !t.IsPtr() {
820                 return false
821         }
822         t = t.Elem()
823         if t == nil {
824                 return false
825         }
826         if t.Kind() != et {
827                 return false
828         }
829         return true
830 }
831
832 // lookdot0 returns the number of fields or methods named s associated
833 // with Type t. If exactly one exists, it will be returned in *save
834 // (if save is not nil).
835 func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
836         u := t
837         if u.IsPtr() {
838                 u = u.Elem()
839         }
840
841         c := 0
842         if u.IsStruct() || u.IsInterface() {
843                 var fields *types.Fields
844                 if u.IsStruct() {
845                         fields = u.Fields()
846                 } else {
847                         fields = u.AllMethods()
848                 }
849                 for _, f := range fields.Slice() {
850                         if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
851                                 if save != nil {
852                                         *save = f
853                                 }
854                                 c++
855                         }
856                 }
857         }
858
859         u = t
860         if t.Sym() != nil && t.IsPtr() && !t.Elem().IsPtr() {
861                 // If t is a defined pointer type, then x.m is shorthand for (*x).m.
862                 u = t.Elem()
863         }
864         u = types.ReceiverBaseType(u)
865         if u != nil {
866                 for _, f := range u.Methods().Slice() {
867                         if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
868                                 if save != nil {
869                                         *save = f
870                                 }
871                                 c++
872                         }
873                 }
874         }
875
876         return c
877 }
878
879 var slist []symlink
880
881 // Code to help generate trampoline functions for methods on embedded
882 // types. These are approx the same as the corresponding AddImplicitDots
883 // routines except that they expect to be called with unique tasks and
884 // they return the actual methods.
885
886 type symlink struct {
887         field *types.Field
888 }
889
890 // TypesOf converts a list of nodes to a list
891 // of types of those nodes.
892 func TypesOf(x []ir.Ntype) []*types.Type {
893         r := make([]*types.Type, len(x))
894         for i, n := range x {
895                 r[i] = n.Type()
896         }
897         return r
898 }
899
900 // addTargs writes out the targs to buffer b as a comma-separated list enclosed by
901 // brackets.
902 func addTargs(b *bytes.Buffer, targs []*types.Type) {
903         b.WriteByte('[')
904         for i, targ := range targs {
905                 if i > 0 {
906                         b.WriteByte(',')
907                 }
908                 // Make sure that type arguments (including type params), are
909                 // uniquely specified. LinkString() eliminates all spaces
910                 // and includes the package path (local package path is "" before
911                 // linker substitution).
912                 tstring := targ.LinkString()
913                 b.WriteString(tstring)
914         }
915         b.WriteString("]")
916 }
917
918 // InstTypeName creates a name for an instantiated type, based on the name of the
919 // generic type and the type args.
920 func InstTypeName(name string, targs []*types.Type) string {
921         b := bytes.NewBufferString(name)
922         addTargs(b, targs)
923         return b.String()
924 }
925
926 // makeInstName1 returns the name of the generic function instantiated with the
927 // given types, which can have type params or shapes, or be concrete types. name is
928 // the name of the generic function or method.
929 func makeInstName1(name string, targs []*types.Type, hasBrackets bool) string {
930         b := bytes.NewBufferString("")
931         i := strings.Index(name, "[")
932         assert(hasBrackets == (i >= 0))
933         if i >= 0 {
934                 b.WriteString(name[0:i])
935         } else {
936                 b.WriteString(name)
937         }
938         addTargs(b, targs)
939         if i >= 0 {
940                 i2 := strings.LastIndex(name[i:], "]")
941                 assert(i2 >= 0)
942                 b.WriteString(name[i+i2+1:])
943         }
944         return b.String()
945 }
946
947 // MakeFuncInstSym makes the unique sym for a stenciled generic function or method,
948 // based on the name of the function gf and the targs. It replaces any
949 // existing bracket type list in the name. MakeInstName asserts that gf has
950 // brackets in its name if and only if hasBrackets is true.
951 //
952 // Names of declared generic functions have no brackets originally, so hasBrackets
953 // should be false. Names of generic methods already have brackets, since the new
954 // type parameter is specified in the generic type of the receiver (e.g. func
955 // (func (v *value[T]).set(...) { ... } has the original name (*value[T]).set.
956 //
957 // The standard naming is something like: 'genFn[int,bool]' for functions and
958 // '(*genType[int,bool]).methodName' for methods
959 //
960 // isMethodNode specifies if the name of a method node is being generated (as opposed
961 // to a name of an instantiation of generic function or name of the shape-based
962 // function that helps implement a method of an instantiated type). For method nodes
963 // on shape types, we prepend "nofunc.", because method nodes for shape types will
964 // have no body, and we want to avoid a name conflict with the shape-based function
965 // that helps implement the same method for fully-instantiated types. Function names
966 // are also created at the end of (*Tsubster).typ1, so we append "nofunc" there as
967 // well, as needed.
968 func MakeFuncInstSym(gf *types.Sym, targs []*types.Type, isMethodNode, hasBrackets bool) *types.Sym {
969         nm := makeInstName1(gf.Name, targs, hasBrackets)
970         if targs[0].HasShape() && isMethodNode {
971                 nm = "nofunc." + nm
972         }
973         return gf.Pkg.Lookup(nm)
974 }
975
976 func MakeDictSym(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.Sym {
977         for _, targ := range targs {
978                 if targ.HasTParam() {
979                         fmt.Printf("FUNCTION %s\n", gf.Name)
980                         for _, targ := range targs {
981                                 fmt.Printf("  PARAM %+v\n", targ)
982                         }
983                         panic("dictionary should always have concrete type args")
984                 }
985         }
986         name := makeInstName1(gf.Name, targs, hasBrackets)
987         name = fmt.Sprintf("%s.%s", objabi.GlobalDictPrefix, name)
988         return gf.Pkg.Lookup(name)
989 }
990
991 func assert(p bool) {
992         base.Assert(p)
993 }
994
995 // List of newly fully-instantiated types who should have their methods generated.
996 var instTypeList []*types.Type
997
998 // NeedInstType adds a new fully-instantiated type to instTypeList.
999 func NeedInstType(t *types.Type) {
1000         instTypeList = append(instTypeList, t)
1001 }
1002
1003 // GetInstTypeList returns the current contents of instTypeList.
1004 func GetInstTypeList() []*types.Type {
1005         r := instTypeList
1006         return r
1007 }
1008
1009 // ClearInstTypeList clears the contents of instTypeList.
1010 func ClearInstTypeList() {
1011         instTypeList = nil
1012 }
1013
1014 // General type substituter, for replacing typeparams with type args.
1015 type Tsubster struct {
1016         Tparams []*types.Type
1017         Targs   []*types.Type
1018         // If non-nil, the substitution map from name nodes in the generic function to the
1019         // name nodes in the new stenciled function.
1020         Vars map[*ir.Name]*ir.Name
1021         // If non-nil, function to substitute an incomplete (TFORW) type.
1022         SubstForwFunc func(*types.Type) *types.Type
1023         // Prevent endless recursion on functions. See #51832.
1024         Funcs map[*types.Type]bool
1025 }
1026
1027 // Typ computes the type obtained by substituting any type parameter or shape in t
1028 // that appears in subst.Tparams with the corresponding type argument in subst.Targs.
1029 // If t contains no type parameters, the result is t; otherwise the result is a new
1030 // type. It deals with recursive types by using TFORW types and finding partially or
1031 // fully created types via sym.Def.
1032 func (ts *Tsubster) Typ(t *types.Type) *types.Type {
1033         // Defer the CheckSize calls until we have fully-defined
1034         // (possibly-recursive) top-level type.
1035         types.DeferCheckSize()
1036         r := ts.typ1(t)
1037         types.ResumeCheckSize()
1038         return r
1039 }
1040
1041 func (ts *Tsubster) typ1(t *types.Type) *types.Type {
1042         hasParamOrShape := t.HasTParam() || t.HasShape()
1043         if !hasParamOrShape && t.Kind() != types.TFUNC {
1044                 // Note: function types need to be copied regardless, as the
1045                 // types of closures may contain declarations that need
1046                 // to be copied. See #45738.
1047                 return t
1048         }
1049
1050         if t.IsTypeParam() || t.IsShape() {
1051                 for i, tp := range ts.Tparams {
1052                         if tp == t {
1053                                 return ts.Targs[i]
1054                         }
1055                 }
1056                 // If t is a simple typeparam T, then t has the name/symbol 'T'
1057                 // and t.Underlying() == t.
1058                 //
1059                 // However, consider the type definition: 'type P[T any] T'. We
1060                 // might use this definition so we can have a variant of type T
1061                 // that we can add new methods to. Suppose t is a reference to
1062                 // P[T]. t has the name 'P[T]', but its kind is TTYPEPARAM,
1063                 // because P[T] is defined as T. If we look at t.Underlying(), it
1064                 // is different, because the name of t.Underlying() is 'T' rather
1065                 // than 'P[T]'. But the kind of t.Underlying() is also TTYPEPARAM.
1066                 // In this case, we do the needed recursive substitution in the
1067                 // case statement below.
1068                 if t.Underlying() == t {
1069                         // t is a simple typeparam that didn't match anything in tparam
1070                         return t
1071                 }
1072                 // t is a more complex typeparam (e.g. P[T], as above, whose
1073                 // definition is just T).
1074                 assert(t.Sym() != nil)
1075         }
1076
1077         var newsym *types.Sym
1078         var neededTargs []*types.Type
1079         var targsChanged bool // == are there any substitutions from this
1080         var forw *types.Type
1081
1082         if t.Sym() != nil && hasParamOrShape {
1083                 // Need to test for t.HasTParam() again because of special TFUNC case above.
1084                 // Translate the type params for this type according to
1085                 // the tparam/targs mapping from subst.
1086                 neededTargs = make([]*types.Type, len(t.RParams()))
1087                 for i, rparam := range t.RParams() {
1088                         neededTargs[i] = ts.typ1(rparam)
1089                         if !types.IdenticalStrict(neededTargs[i], rparam) {
1090                                 targsChanged = true
1091                         }
1092                 }
1093                 // For a named (defined) type, we have to change the name of the
1094                 // type as well. We do this first, so we can look up if we've
1095                 // already seen this type during this substitution or other
1096                 // definitions/substitutions.
1097                 genName := genericTypeName(t.Sym())
1098                 newsym = t.Sym().Pkg.Lookup(InstTypeName(genName, neededTargs))
1099                 if newsym.Def != nil {
1100                         // We've already created this instantiated defined type.
1101                         return newsym.Def.Type()
1102                 }
1103
1104                 // In order to deal with recursive generic types, create a TFORW
1105                 // type initially and set the Def field of its sym, so it can be
1106                 // found if this type appears recursively within the type.
1107                 forw = NewIncompleteNamedType(t.Pos(), newsym)
1108                 //println("Creating new type by sub", newsym.Name, forw.HasTParam())
1109                 forw.SetRParams(neededTargs)
1110                 // Copy the OrigType from the re-instantiated type (which is the sym of
1111                 // the base generic type).
1112                 assert(t.OrigType() != nil)
1113                 forw.SetOrigType(t.OrigType())
1114         }
1115
1116         var newt *types.Type
1117
1118         switch t.Kind() {
1119         case types.TTYPEPARAM:
1120                 if t.Sym() == newsym && !targsChanged {
1121                         // The substitution did not change the type.
1122                         return t
1123                 }
1124                 // Substitute the underlying typeparam (e.g. T in P[T], see
1125                 // the example describing type P[T] above).
1126                 newt = ts.typ1(t.Underlying())
1127                 assert(newt != t)
1128
1129         case types.TARRAY:
1130                 elem := t.Elem()
1131                 newelem := ts.typ1(elem)
1132                 if newelem != elem || targsChanged {
1133                         newt = types.NewArray(newelem, t.NumElem())
1134                 }
1135
1136         case types.TPTR:
1137                 elem := t.Elem()
1138                 newelem := ts.typ1(elem)
1139                 if newelem != elem || targsChanged {
1140                         newt = types.NewPtr(newelem)
1141                 }
1142
1143         case types.TSLICE:
1144                 elem := t.Elem()
1145                 newelem := ts.typ1(elem)
1146                 if newelem != elem || targsChanged {
1147                         newt = types.NewSlice(newelem)
1148                 }
1149
1150         case types.TSTRUCT:
1151                 newt = ts.tstruct(t, targsChanged)
1152                 if newt == t {
1153                         newt = nil
1154                 }
1155
1156         case types.TFUNC:
1157                 // watch out for endless recursion on plain function types that mention themselves, e.g. "type T func() T"
1158                 if !hasParamOrShape {
1159                         if ts.Funcs[t] { // Visit such function types only once.
1160                                 return t
1161                         }
1162                         if ts.Funcs == nil {
1163                                 // allocate lazily
1164                                 ts.Funcs = make(map[*types.Type]bool)
1165                         }
1166                         ts.Funcs[t] = true
1167                 }
1168                 newrecvs := ts.tstruct(t.Recvs(), false)
1169                 newparams := ts.tstruct(t.Params(), false)
1170                 newresults := ts.tstruct(t.Results(), false)
1171                 // Translate the tparams of a signature.
1172                 newtparams := ts.tstruct(t.TParams(), false)
1173                 if newrecvs != t.Recvs() || newparams != t.Params() ||
1174                         newresults != t.Results() || newtparams != t.TParams() || targsChanged {
1175                         // If any types have changed, then the all the fields of
1176                         // of recv, params, and results must be copied, because they have
1177                         // offset fields that are dependent, and so must have an
1178                         // independent copy for each new signature.
1179                         var newrecv *types.Field
1180                         if newrecvs.NumFields() > 0 {
1181                                 if newrecvs == t.Recvs() {
1182                                         newrecvs = ts.tstruct(t.Recvs(), true)
1183                                 }
1184                                 newrecv = newrecvs.Field(0)
1185                         }
1186                         if newparams == t.Params() {
1187                                 newparams = ts.tstruct(t.Params(), true)
1188                         }
1189                         if newresults == t.Results() {
1190                                 newresults = ts.tstruct(t.Results(), true)
1191                         }
1192                         var tparamfields []*types.Field
1193                         if newtparams.HasTParam() {
1194                                 tparamfields = newtparams.FieldSlice()
1195                         } else {
1196                                 // Completely remove the tparams from the resulting
1197                                 // signature, if the tparams are now concrete types.
1198                                 tparamfields = nil
1199                         }
1200                         newt = types.NewSignature(t.Pkg(), newrecv, tparamfields,
1201                                 newparams.FieldSlice(), newresults.FieldSlice())
1202                 }
1203                 if !hasParamOrShape {
1204                         delete(ts.Funcs, t)
1205                 }
1206
1207         case types.TINTER:
1208                 newt = ts.tinter(t, targsChanged)
1209                 if newt == t {
1210                         newt = nil
1211                 }
1212
1213         case types.TMAP:
1214                 newkey := ts.typ1(t.Key())
1215                 newval := ts.typ1(t.Elem())
1216                 if newkey != t.Key() || newval != t.Elem() || targsChanged {
1217                         newt = types.NewMap(newkey, newval)
1218                 }
1219
1220         case types.TCHAN:
1221                 elem := t.Elem()
1222                 newelem := ts.typ1(elem)
1223                 if newelem != elem || targsChanged {
1224                         newt = types.NewChan(newelem, t.ChanDir())
1225                 }
1226         case types.TFORW:
1227                 if ts.SubstForwFunc != nil {
1228                         return ts.SubstForwFunc(forw)
1229                 } else {
1230                         assert(false)
1231                 }
1232         case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
1233                 types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64,
1234                 types.TUINTPTR, types.TBOOL, types.TSTRING, types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128, types.TUNSAFEPTR:
1235                 newt = t.Underlying()
1236         case types.TUNION:
1237                 nt := t.NumTerms()
1238                 newterms := make([]*types.Type, nt)
1239                 tildes := make([]bool, nt)
1240                 changed := false
1241                 for i := 0; i < nt; i++ {
1242                         term, tilde := t.Term(i)
1243                         tildes[i] = tilde
1244                         newterms[i] = ts.typ1(term)
1245                         if newterms[i] != term {
1246                                 changed = true
1247                         }
1248                 }
1249                 if changed {
1250                         newt = types.NewUnion(newterms, tildes)
1251                 }
1252         default:
1253                 panic(fmt.Sprintf("Bad type in (*TSubster).Typ: %v", t.Kind()))
1254         }
1255         if newt == nil {
1256                 // Even though there were typeparams in the type, there may be no
1257                 // change if this is a function type for a function call (which will
1258                 // have its own tparams/targs in the function instantiation).
1259                 return t
1260         }
1261
1262         if forw != nil {
1263                 forw.SetUnderlying(newt)
1264                 newt = forw
1265         }
1266
1267         if !newt.HasTParam() && !newt.IsFuncArgStruct() {
1268                 // Calculate the size of any new types created. These will be
1269                 // deferred until the top-level ts.Typ() or g.typ() (if this is
1270                 // called from g.fillinMethods()).
1271                 types.CheckSize(newt)
1272         }
1273
1274         if t.Kind() != types.TINTER && t.Methods().Len() > 0 {
1275                 // Fill in the method info for the new type.
1276                 var newfields []*types.Field
1277                 newfields = make([]*types.Field, t.Methods().Len())
1278                 for i, f := range t.Methods().Slice() {
1279                         t2 := ts.typ1(f.Type)
1280                         oldsym := f.Nname.Sym()
1281
1282                         // Use the name of the substituted receiver to create the
1283                         // method name, since the receiver name may have many levels
1284                         // of nesting (brackets) with type names to be substituted.
1285                         recvType := t2.Recv().Type
1286                         var nm string
1287                         if recvType.IsPtr() {
1288                                 recvType = recvType.Elem()
1289                                 nm = "(*" + recvType.Sym().Name + ")." + f.Sym.Name
1290                         } else {
1291                                 nm = recvType.Sym().Name + "." + f.Sym.Name
1292                         }
1293                         if recvType.RParams()[0].HasShape() {
1294                                 // We add "nofunc" to methods of shape type to avoid
1295                                 // conflict with the name of the shape-based helper
1296                                 // function. See header comment of MakeFuncInstSym.
1297                                 nm = "nofunc." + nm
1298                         }
1299                         newsym := oldsym.Pkg.Lookup(nm)
1300                         var nname *ir.Name
1301                         if newsym.Def != nil {
1302                                 nname = newsym.Def.(*ir.Name)
1303                         } else {
1304                                 nname = ir.NewNameAt(f.Pos, newsym)
1305                                 nname.SetType(t2)
1306                                 ir.MarkFunc(nname)
1307                                 newsym.Def = nname
1308                         }
1309                         newfields[i] = types.NewField(f.Pos, f.Sym, t2)
1310                         newfields[i].Nname = nname
1311                 }
1312                 newt.Methods().Set(newfields)
1313                 if !newt.HasTParam() && !newt.HasShape() {
1314                         // Generate all the methods for a new fully-instantiated type.
1315
1316                         NeedInstType(newt)
1317                 }
1318         }
1319         return newt
1320 }
1321
1322 // tstruct substitutes type params in types of the fields of a structure type. For
1323 // each field, tstruct copies the Nname, and translates it if Nname is in
1324 // ts.vars. To always force the creation of a new (top-level) struct,
1325 // regardless of whether anything changed with the types or names of the struct's
1326 // fields, set force to true.
1327 func (ts *Tsubster) tstruct(t *types.Type, force bool) *types.Type {
1328         if t.NumFields() == 0 {
1329                 if t.HasTParam() || t.HasShape() {
1330                         // For an empty struct, we need to return a new type, if
1331                         // substituting from a generic type or shape type, since it
1332                         // will change HasTParam/HasShape flags.
1333                         return types.NewStruct(t.Pkg(), nil)
1334                 }
1335                 return t
1336         }
1337         var newfields []*types.Field
1338         if force {
1339                 newfields = make([]*types.Field, t.NumFields())
1340         }
1341         for i, f := range t.Fields().Slice() {
1342                 t2 := ts.typ1(f.Type)
1343                 if (t2 != f.Type || f.Nname != nil) && newfields == nil {
1344                         newfields = make([]*types.Field, t.NumFields())
1345                         for j := 0; j < i; j++ {
1346                                 newfields[j] = t.Field(j)
1347                         }
1348                 }
1349                 if newfields != nil {
1350                         newfields[i] = types.NewField(f.Pos, f.Sym, t2)
1351                         newfields[i].Embedded = f.Embedded
1352                         newfields[i].Note = f.Note
1353                         if f.IsDDD() {
1354                                 newfields[i].SetIsDDD(true)
1355                         }
1356                         if f.Nointerface() {
1357                                 newfields[i].SetNointerface(true)
1358                         }
1359                         if f.Nname != nil && ts.Vars != nil {
1360                                 n := f.Nname.(*ir.Name)
1361                                 v := ts.Vars[n]
1362                                 if v != nil {
1363                                         // This is the case where we are
1364                                         // translating the type of the function we
1365                                         // are substituting, so its dcls are in
1366                                         // the subst.ts.vars table, and we want to
1367                                         // change to reference the new dcl.
1368                                         newfields[i].Nname = v
1369                                 } else if ir.IsBlank(n) {
1370                                         // Blank variable is not dcl list. Make a
1371                                         // new one to not share.
1372                                         m := ir.NewNameAt(n.Pos(), ir.BlankNode.Sym())
1373                                         m.SetType(n.Type())
1374                                         m.SetTypecheck(1)
1375                                         newfields[i].Nname = m
1376                                 } else {
1377                                         // This is the case where we are
1378                                         // translating the type of a function
1379                                         // reference inside the function we are
1380                                         // substituting, so we leave the Nname
1381                                         // value as is.
1382                                         newfields[i].Nname = f.Nname
1383                                 }
1384                         }
1385                 }
1386         }
1387         if newfields != nil {
1388                 news := types.NewStruct(t.Pkg(), newfields)
1389                 news.StructType().Funarg = t.StructType().Funarg
1390                 return news
1391         }
1392         return t
1393
1394 }
1395
1396 // tinter substitutes type params in types of the methods of an interface type.
1397 func (ts *Tsubster) tinter(t *types.Type, force bool) *types.Type {
1398         if t.Methods().Len() == 0 {
1399                 if t.HasTParam() || t.HasShape() {
1400                         // For an empty interface, we need to return a new type, if
1401                         // substituting from a generic type or shape type, since
1402                         // since it will change HasTParam/HasShape flags.
1403                         return types.NewInterface(t.Pkg(), nil, false)
1404                 }
1405                 return t
1406         }
1407         var newfields []*types.Field
1408         if force {
1409                 newfields = make([]*types.Field, t.Methods().Len())
1410         }
1411         for i, f := range t.Methods().Slice() {
1412                 t2 := ts.typ1(f.Type)
1413                 if (t2 != f.Type || f.Nname != nil) && newfields == nil {
1414                         newfields = make([]*types.Field, t.Methods().Len())
1415                         for j := 0; j < i; j++ {
1416                                 newfields[j] = t.Methods().Index(j)
1417                         }
1418                 }
1419                 if newfields != nil {
1420                         newfields[i] = types.NewField(f.Pos, f.Sym, t2)
1421                 }
1422         }
1423         if newfields != nil {
1424                 return types.NewInterface(t.Pkg(), newfields, t.IsImplicit())
1425         }
1426         return t
1427 }
1428
1429 // genericTypeName returns the name of the base generic type for the type named by
1430 // sym. It simply returns the name obtained by removing everything after the
1431 // first bracket ("[").
1432 func genericTypeName(sym *types.Sym) string {
1433         return sym.Name[0:strings.Index(sym.Name, "[")]
1434 }
1435
1436 // getShapes appends the list of the shape types that are used within type t to
1437 // listp. The type traversal is simplified for two reasons: (1) we can always stop a
1438 // type traversal when t.HasShape() is false; and (2) shape types can't appear inside
1439 // a named type, except for the type args of a generic type. So, the traversal will
1440 // always stop before we have to deal with recursive types.
1441 func getShapes(t *types.Type, listp *[]*types.Type) {
1442         if !t.HasShape() {
1443                 return
1444         }
1445         if t.IsShape() {
1446                 *listp = append(*listp, t)
1447                 return
1448         }
1449
1450         if t.Sym() != nil {
1451                 // A named type can't have shapes in it, except for type args of a
1452                 // generic type. We will have to deal with this differently once we
1453                 // alloc local types in generic functions (#47631).
1454                 for _, rparam := range t.RParams() {
1455                         getShapes(rparam, listp)
1456                 }
1457                 return
1458         }
1459
1460         switch t.Kind() {
1461         case types.TARRAY, types.TPTR, types.TSLICE, types.TCHAN:
1462                 getShapes(t.Elem(), listp)
1463
1464         case types.TSTRUCT:
1465                 for _, f := range t.FieldSlice() {
1466                         getShapes(f.Type, listp)
1467                 }
1468
1469         case types.TFUNC:
1470                 for _, f := range t.Recvs().FieldSlice() {
1471                         getShapes(f.Type, listp)
1472                 }
1473                 for _, f := range t.Params().FieldSlice() {
1474                         getShapes(f.Type, listp)
1475                 }
1476                 for _, f := range t.Results().FieldSlice() {
1477                         getShapes(f.Type, listp)
1478                 }
1479                 for _, f := range t.TParams().FieldSlice() {
1480                         getShapes(f.Type, listp)
1481                 }
1482
1483         case types.TINTER:
1484                 for _, f := range t.Methods().Slice() {
1485                         getShapes(f.Type, listp)
1486                 }
1487
1488         case types.TMAP:
1489                 getShapes(t.Key(), listp)
1490                 getShapes(t.Elem(), listp)
1491
1492         default:
1493                 panic(fmt.Sprintf("Bad type in getShapes: %v", t.Kind()))
1494         }
1495
1496 }
1497
1498 // Shapify takes a concrete type and a type param index, and returns a GCshape type that can
1499 // be used in place of the input type and still generate identical code.
1500 // No methods are added - all methods calls directly on a shape should
1501 // be done by converting to an interface using the dictionary.
1502 //
1503 // For now, we only consider two types to have the same shape, if they have exactly
1504 // the same underlying type or they are both pointer types.
1505 //
1506 // tparam is the associated typeparam - it must be TTYPEPARAM type. If there is a
1507 // structural type for the associated type param (not common), then a pointer type t
1508 // is mapped to its underlying type, rather than being merged with other pointers.
1509 //
1510 // Shape types are also distinguished by the index of the type in a type param/arg
1511 // list. We need to do this so we can distinguish and substitute properly for two
1512 // type params in the same function that have the same shape for a particular
1513 // instantiation.
1514 func Shapify(t *types.Type, index int, tparam *types.Type) *types.Type {
1515         assert(!t.IsShape())
1516         if t.HasShape() {
1517                 // We are sometimes dealing with types from a shape instantiation
1518                 // that were constructed from existing shape types, so t may
1519                 // sometimes have shape types inside it. In that case, we find all
1520                 // those shape types with getShapes() and replace them with their
1521                 // underlying type.
1522                 //
1523                 // If we don't do this, we may create extra unneeded shape types that
1524                 // have these other shape types embedded in them. This may lead to
1525                 // generating extra shape instantiations, and a mismatch between the
1526                 // instantiations that we used in generating dictionaries and the
1527                 // instantations that are actually called. (#51303).
1528                 list := []*types.Type{}
1529                 getShapes(t, &list)
1530                 list2 := make([]*types.Type, len(list))
1531                 for i, shape := range list {
1532                         list2[i] = shape.Underlying()
1533                 }
1534                 ts := Tsubster{
1535                         Tparams: list,
1536                         Targs:   list2,
1537                 }
1538                 t = ts.Typ(t)
1539         }
1540         // Map all types with the same underlying type to the same shape.
1541         u := t.Underlying()
1542
1543         // All pointers have the same shape.
1544         // TODO: Make unsafe.Pointer the same shape as normal pointers.
1545         // Note: pointers to arrays are special because of slice-to-array-pointer
1546         // conversions. See issue 49295.
1547         if u.Kind() == types.TPTR && u.Elem().Kind() != types.TARRAY &&
1548                 tparam.Bound().StructuralType() == nil && !u.Elem().NotInHeap() {
1549                 u = types.Types[types.TUINT8].PtrTo()
1550         }
1551
1552         submap := shapeMap[index]
1553         if submap == nil {
1554                 submap = map[*types.Type]*types.Type{}
1555                 shapeMap[index] = submap
1556         }
1557         if s := submap[u]; s != nil {
1558                 return s
1559         }
1560
1561         // LinkString specifies the type uniquely, but has no spaces.
1562         nm := fmt.Sprintf("%s_%d", u.LinkString(), index)
1563         sym := types.ShapePkg.Lookup(nm)
1564         if sym.Def != nil {
1565                 // Use any existing type with the same name
1566                 submap[u] = sym.Def.Type()
1567                 return submap[u]
1568         }
1569         name := ir.NewDeclNameAt(u.Pos(), ir.OTYPE, sym)
1570         s := types.NewNamed(name)
1571         sym.Def = name
1572         s.SetUnderlying(u)
1573         s.SetIsShape(true)
1574         s.SetHasShape(true)
1575         types.CalcSize(s)
1576         name.SetType(s)
1577         name.SetTypecheck(1)
1578         submap[u] = s
1579         return s
1580 }
1581
1582 var shapeMap = map[int]map[*types.Type]*types.Type{}