]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/typecheck/subr.go
cmd/compile/internal/reflectdata: share hmap and hiter types
[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         "fmt"
9         "sort"
10         "strings"
11
12         "cmd/compile/internal/base"
13         "cmd/compile/internal/ir"
14         "cmd/compile/internal/types"
15         "cmd/internal/obj"
16         "cmd/internal/src"
17 )
18
19 func AssignConv(n ir.Node, t *types.Type, context string) ir.Node {
20         return assignconvfn(n, t, func() string { return context })
21 }
22
23 // LookupNum returns types.LocalPkg.LookupNum(prefix, n).
24 func LookupNum(prefix string, n int) *types.Sym {
25         return types.LocalPkg.LookupNum(prefix, n)
26 }
27
28 // Given funarg struct list, return list of fn args.
29 func NewFuncParams(origs []*types.Field, mustname bool) []*types.Field {
30         res := make([]*types.Field, len(origs))
31         for i, orig := range origs {
32                 s := orig.Sym
33                 if mustname && (s == nil || s.Name == "_") {
34                         // invent a name so that we can refer to it in the trampoline
35                         s = LookupNum(".anon", i)
36                 } else if s != nil && s.Pkg != types.LocalPkg {
37                         // TODO(mdempsky): Preserve original position, name, and package.
38                         s = Lookup(s.Name)
39                 }
40                 p := types.NewField(orig.Pos, s, orig.Type)
41                 p.SetIsDDD(orig.IsDDD())
42                 res[i] = p
43         }
44         return res
45 }
46
47 // NodAddr returns a node representing &n at base.Pos.
48 func NodAddr(n ir.Node) *ir.AddrExpr {
49         return NodAddrAt(base.Pos, n)
50 }
51
52 // NodAddrAt returns a node representing &n at position pos.
53 func NodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
54         n = markAddrOf(n)
55         return ir.NewAddrExpr(pos, n)
56 }
57
58 func markAddrOf(n ir.Node) ir.Node {
59         if IncrementalAddrtaken {
60                 // We can only do incremental addrtaken computation when it is ok
61                 // to typecheck the argument of the OADDR. That's only safe after the
62                 // main typecheck has completed, and not loading the inlined body.
63                 // The argument to OADDR needs to be typechecked because &x[i] takes
64                 // the address of x if x is an array, but not if x is a slice.
65                 // Note: OuterValue doesn't work correctly until n is typechecked.
66                 n = typecheck(n, ctxExpr)
67                 if x := ir.OuterValue(n); x.Op() == ir.ONAME {
68                         x.Name().SetAddrtaken(true)
69                 }
70         } else {
71                 // Remember that we built an OADDR without computing the Addrtaken bit for
72                 // its argument. We'll do that later in bulk using computeAddrtaken.
73                 DirtyAddrtaken = true
74         }
75         return n
76 }
77
78 // If IncrementalAddrtaken is false, we do not compute Addrtaken for an OADDR Node
79 // when it is built. The Addrtaken bits are set in bulk by computeAddrtaken.
80 // If IncrementalAddrtaken is true, then when an OADDR Node is built the Addrtaken
81 // field of its argument is updated immediately.
82 var IncrementalAddrtaken = false
83
84 // If DirtyAddrtaken is true, then there are OADDR whose corresponding arguments
85 // have not yet been marked as Addrtaken.
86 var DirtyAddrtaken = false
87
88 func ComputeAddrtaken(funcs []*ir.Func) {
89         var doVisit func(n ir.Node)
90         doVisit = func(n ir.Node) {
91                 if n.Op() == ir.OADDR {
92                         if x := ir.OuterValue(n.(*ir.AddrExpr).X); x.Op() == ir.ONAME {
93                                 x.Name().SetAddrtaken(true)
94                                 if x.Name().IsClosureVar() {
95                                         // Mark the original variable as Addrtaken so that capturevars
96                                         // knows not to pass it by value.
97                                         x.Name().Defn.Name().SetAddrtaken(true)
98                                 }
99                         }
100                 }
101                 if n.Op() == ir.OCLOSURE {
102                         ir.VisitList(n.(*ir.ClosureExpr).Func.Body, doVisit)
103                 }
104         }
105
106         for _, fn := range funcs {
107                 ir.Visit(fn, doVisit)
108         }
109 }
110
111 // LinksymAddr returns a new expression that evaluates to the address
112 // of lsym. typ specifies the type of the addressed memory.
113 func LinksymAddr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *ir.AddrExpr {
114         n := ir.NewLinksymExpr(pos, lsym, typ)
115         return Expr(NodAddrAt(pos, n)).(*ir.AddrExpr)
116 }
117
118 func NodNil() ir.Node {
119         return ir.NewNilExpr(base.Pos, types.Types[types.TNIL])
120 }
121
122 // AddImplicitDots finds missing fields in obj.field that
123 // will give the shortest unique addressing and
124 // modifies the tree with missing field names.
125 func AddImplicitDots(n *ir.SelectorExpr) *ir.SelectorExpr {
126         n.X = typecheck(n.X, ctxType|ctxExpr)
127         t := n.X.Type()
128         if t == nil {
129                 return n
130         }
131
132         if n.X.Op() == ir.OTYPE {
133                 return n
134         }
135
136         s := n.Sel
137         if s == nil {
138                 return n
139         }
140
141         switch path, ambig := dotpath(s, t, nil, false); {
142         case path != nil:
143                 // rebuild elided dots
144                 for c := len(path) - 1; c >= 0; c-- {
145                         dot := ir.NewSelectorExpr(n.Pos(), ir.ODOT, n.X, path[c].field.Sym)
146                         dot.SetImplicit(true)
147                         dot.SetType(path[c].field.Type)
148                         n.X = dot
149                 }
150         case ambig:
151                 base.Errorf("ambiguous selector %v", n)
152                 n.X = nil
153         }
154
155         return n
156 }
157
158 // CalcMethods calculates all the methods (including embedding) of a non-interface
159 // type t.
160 func CalcMethods(t *types.Type) {
161         if t == nil || t.AllMethods().Len() != 0 {
162                 return
163         }
164
165         // mark top-level method symbols
166         // so that expand1 doesn't consider them.
167         for _, f := range t.Methods().Slice() {
168                 f.Sym.SetUniq(true)
169         }
170
171         // generate all reachable methods
172         slist = slist[:0]
173         expand1(t, true)
174
175         // check each method to be uniquely reachable
176         var ms []*types.Field
177         for i, sl := range slist {
178                 slist[i].field = nil
179                 sl.field.Sym.SetUniq(false)
180
181                 var f *types.Field
182                 path, _ := dotpath(sl.field.Sym, t, &f, false)
183                 if path == nil {
184                         continue
185                 }
186
187                 // dotpath may have dug out arbitrary fields, we only want methods.
188                 if !f.IsMethod() {
189                         continue
190                 }
191
192                 // add it to the base type method list
193                 f = f.Copy()
194                 f.Embedded = 1 // needs a trampoline
195                 for _, d := range path {
196                         if d.field.Type.IsPtr() {
197                                 f.Embedded = 2
198                                 break
199                         }
200                 }
201                 ms = append(ms, f)
202         }
203
204         for _, f := range t.Methods().Slice() {
205                 f.Sym.SetUniq(false)
206         }
207
208         ms = append(ms, t.Methods().Slice()...)
209         sort.Sort(types.MethodsByName(ms))
210         t.SetAllMethods(ms)
211 }
212
213 // adddot1 returns the number of fields or methods named s at depth d in Type t.
214 // If exactly one exists, it will be returned in *save (if save is not nil),
215 // and dotlist will contain the path of embedded fields traversed to find it,
216 // in reverse order. If none exist, more will indicate whether t contains any
217 // embedded fields at depth d, so callers can decide whether to retry at
218 // a greater depth.
219 func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) {
220         if t.Recur() {
221                 return
222         }
223         t.SetRecur(true)
224         defer t.SetRecur(false)
225
226         var u *types.Type
227         d--
228         if d < 0 {
229                 // We've reached our target depth. If t has any fields/methods
230                 // named s, then we're done. Otherwise, we still need to check
231                 // below for embedded fields.
232                 c = lookdot0(s, t, save, ignorecase)
233                 if c != 0 {
234                         return c, false
235                 }
236         }
237
238         u = t
239         if u.IsPtr() {
240                 u = u.Elem()
241         }
242         if !u.IsStruct() && !u.IsInterface() {
243                 return c, false
244         }
245
246         var fields *types.Fields
247         if u.IsStruct() {
248                 fields = u.Fields()
249         } else {
250                 fields = u.AllMethods()
251         }
252         for _, f := range fields.Slice() {
253                 if f.Embedded == 0 || f.Sym == nil {
254                         continue
255                 }
256                 if d < 0 {
257                         // Found an embedded field at target depth.
258                         return c, true
259                 }
260                 a, more1 := adddot1(s, f.Type, d, save, ignorecase)
261                 if a != 0 && c == 0 {
262                         dotlist[d].field = f
263                 }
264                 c += a
265                 if more1 {
266                         more = true
267                 }
268         }
269
270         return c, more
271 }
272
273 // dotlist is used by adddot1 to record the path of embedded fields
274 // used to access a target field or method.
275 // Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
276 var dotlist = make([]dlist, 10)
277
278 // Convert node n for assignment to type t.
279 func assignconvfn(n ir.Node, t *types.Type, context func() string) ir.Node {
280         if n == nil || n.Type() == nil {
281                 return n
282         }
283
284         if t.Kind() == types.TBLANK && n.Type().Kind() == types.TNIL {
285                 base.Errorf("use of untyped nil")
286         }
287
288         n = convlit1(n, t, false, context)
289         if n.Type() == nil {
290                 base.Fatalf("cannot assign %v to %v", n, t)
291         }
292         if n.Type().IsUntyped() {
293                 base.Fatalf("%L has untyped type", n)
294         }
295         if t.Kind() == types.TBLANK {
296                 return n
297         }
298         if types.Identical(n.Type(), t) {
299                 return n
300         }
301
302         op, why := Assignop(n.Type(), t)
303         if op == ir.OXXX {
304                 base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
305                 op = ir.OCONV
306         }
307
308         r := ir.NewConvExpr(base.Pos, op, t, n)
309         r.SetTypecheck(1)
310         r.SetImplicit(true)
311         return r
312 }
313
314 // Is type src assignment compatible to type dst?
315 // If so, return op code to use in conversion.
316 // If not, return OXXX. In this case, the string return parameter may
317 // hold a reason why. In all other cases, it'll be the empty string.
318 func Assignop(src, dst *types.Type) (ir.Op, string) {
319         if src == dst {
320                 return ir.OCONVNOP, ""
321         }
322         if src == nil || dst == nil || src.Kind() == types.TFORW || dst.Kind() == types.TFORW || src.Underlying() == nil || dst.Underlying() == nil {
323                 return ir.OXXX, ""
324         }
325
326         // 1. src type is identical to dst.
327         if types.Identical(src, dst) {
328                 return ir.OCONVNOP, ""
329         }
330         return Assignop1(src, dst)
331 }
332
333 func Assignop1(src, dst *types.Type) (ir.Op, string) {
334         // 2. src and dst have identical underlying types and
335         //   a. either src or dst is not a named type, or
336         //   b. both are empty interface types, or
337         //   c. at least one is a gcshape type.
338         // For assignable but different non-empty interface types,
339         // we want to recompute the itab. Recomputing the itab ensures
340         // that itabs are unique (thus an interface with a compile-time
341         // type I has an itab with interface type I).
342         if types.Identical(src.Underlying(), dst.Underlying()) {
343                 if src.IsEmptyInterface() {
344                         // Conversion between two empty interfaces
345                         // requires no code.
346                         return ir.OCONVNOP, ""
347                 }
348                 if (src.Sym() == nil || dst.Sym() == nil) && !src.IsInterface() {
349                         // Conversion between two types, at least one unnamed,
350                         // needs no conversion. The exception is nonempty interfaces
351                         // which need to have their itab updated.
352                         return ir.OCONVNOP, ""
353                 }
354                 if src.IsShape() || dst.IsShape() {
355                         // Conversion between a shape type and one of the types
356                         // it represents also needs no conversion.
357                         return ir.OCONVNOP, ""
358                 }
359         }
360
361         // 3. dst is an interface type and src implements dst.
362         if dst.IsInterface() && src.Kind() != types.TNIL {
363                 if src.IsShape() {
364                         // Shape types implement things they have already
365                         // been typechecked to implement, even if they
366                         // don't have the methods for them.
367                         return ir.OCONVIFACE, ""
368                 }
369                 if src.HasShape() {
370                         // Unified IR uses OCONVIFACE for converting all derived types
371                         // to interface type, not just type arguments themselves.
372                         return ir.OCONVIFACE, ""
373                 }
374
375                 why := ImplementsExplain(src, dst)
376                 if why == "" {
377                         return ir.OCONVIFACE, ""
378                 }
379                 return ir.OXXX, ":\n\t" + why
380         }
381
382         if isptrto(dst, types.TINTER) {
383                 why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
384                 return ir.OXXX, why
385         }
386
387         if src.IsInterface() && dst.Kind() != types.TBLANK {
388                 var why string
389                 if Implements(dst, src) {
390                         why = ": need type assertion"
391                 }
392                 return ir.OXXX, why
393         }
394
395         // 4. src is a bidirectional channel value, dst is a channel type,
396         // src and dst have identical element types, and
397         // either src or dst is not a named type.
398         if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
399                 if types.Identical(src.Elem(), dst.Elem()) && (src.Sym() == nil || dst.Sym() == nil) {
400                         return ir.OCONVNOP, ""
401                 }
402         }
403
404         // 5. src is the predeclared identifier nil and dst is a nillable type.
405         if src.Kind() == types.TNIL {
406                 switch dst.Kind() {
407                 case types.TPTR,
408                         types.TFUNC,
409                         types.TMAP,
410                         types.TCHAN,
411                         types.TINTER,
412                         types.TSLICE:
413                         return ir.OCONVNOP, ""
414                 }
415         }
416
417         // 6. rule about untyped constants - already converted by DefaultLit.
418
419         // 7. Any typed value can be assigned to the blank identifier.
420         if dst.Kind() == types.TBLANK {
421                 return ir.OCONVNOP, ""
422         }
423
424         return ir.OXXX, ""
425 }
426
427 // Can we convert a value of type src to a value of type dst?
428 // If so, return op code to use in conversion (maybe OCONVNOP).
429 // If not, return OXXX. In this case, the string return parameter may
430 // hold a reason why. In all other cases, it'll be the empty string.
431 // srcConstant indicates whether the value of type src is a constant.
432 func Convertop(srcConstant bool, src, dst *types.Type) (ir.Op, string) {
433         if src == dst {
434                 return ir.OCONVNOP, ""
435         }
436         if src == nil || dst == nil {
437                 return ir.OXXX, ""
438         }
439
440         // Conversions from regular to not-in-heap are not allowed
441         // (unless it's unsafe.Pointer). These are runtime-specific
442         // rules.
443         // (a) Disallow (*T) to (*U) where T is not-in-heap but U isn't.
444         if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
445                 why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
446                 return ir.OXXX, why
447         }
448         // (b) Disallow string to []T where T is not-in-heap.
449         if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Kind() == types.ByteType.Kind() || dst.Elem().Kind() == types.RuneType.Kind()) {
450                 why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
451                 return ir.OXXX, why
452         }
453
454         // 1. src can be assigned to dst.
455         op, why := Assignop(src, dst)
456         if op != ir.OXXX {
457                 return op, why
458         }
459
460         // The rules for interfaces are no different in conversions
461         // than assignments. If interfaces are involved, stop now
462         // with the good message from assignop.
463         // Otherwise clear the error.
464         if src.IsInterface() || dst.IsInterface() {
465                 return ir.OXXX, why
466         }
467
468         // 2. Ignoring struct tags, src and dst have identical underlying types.
469         if types.IdenticalIgnoreTags(src.Underlying(), dst.Underlying()) {
470                 return ir.OCONVNOP, ""
471         }
472
473         // 3. src and dst are unnamed pointer types and, ignoring struct tags,
474         // their base types have identical underlying types.
475         if src.IsPtr() && dst.IsPtr() && src.Sym() == nil && dst.Sym() == nil {
476                 if types.IdenticalIgnoreTags(src.Elem().Underlying(), dst.Elem().Underlying()) {
477                         return ir.OCONVNOP, ""
478                 }
479         }
480
481         // 4. src and dst are both integer or floating point types.
482         if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
483                 if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
484                         return ir.OCONVNOP, ""
485                 }
486                 return ir.OCONV, ""
487         }
488
489         // 5. src and dst are both complex types.
490         if src.IsComplex() && dst.IsComplex() {
491                 if types.SimType[src.Kind()] == types.SimType[dst.Kind()] {
492                         return ir.OCONVNOP, ""
493                 }
494                 return ir.OCONV, ""
495         }
496
497         // Special case for constant conversions: any numeric
498         // conversion is potentially okay. We'll validate further
499         // within evconst. See #38117.
500         if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
501                 return ir.OCONV, ""
502         }
503
504         // 6. src is an integer or has type []byte or []rune
505         // and dst is a string type.
506         if src.IsInteger() && dst.IsString() {
507                 return ir.ORUNESTR, ""
508         }
509
510         if src.IsSlice() && dst.IsString() {
511                 if src.Elem().Kind() == types.ByteType.Kind() {
512                         return ir.OBYTES2STR, ""
513                 }
514                 if src.Elem().Kind() == types.RuneType.Kind() {
515                         return ir.ORUNES2STR, ""
516                 }
517         }
518
519         // 7. src is a string and dst is []byte or []rune.
520         // String to slice.
521         if src.IsString() && dst.IsSlice() {
522                 if dst.Elem().Kind() == types.ByteType.Kind() {
523                         return ir.OSTR2BYTES, ""
524                 }
525                 if dst.Elem().Kind() == types.RuneType.Kind() {
526                         return ir.OSTR2RUNES, ""
527                 }
528         }
529
530         // 8. src is a pointer or uintptr and dst is unsafe.Pointer.
531         if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() {
532                 return ir.OCONVNOP, ""
533         }
534
535         // 9. src is unsafe.Pointer and dst is a pointer or uintptr.
536         if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
537                 return ir.OCONVNOP, ""
538         }
539
540         // 10. src is a slice and dst is an array or pointer-to-array.
541         // They must have same element type.
542         if src.IsSlice() {
543                 if dst.IsArray() && types.Identical(src.Elem(), dst.Elem()) {
544                         return ir.OSLICE2ARR, ""
545                 }
546                 if dst.IsPtr() && dst.Elem().IsArray() &&
547                         types.Identical(src.Elem(), dst.Elem().Elem()) {
548                         return ir.OSLICE2ARRPTR, ""
549                 }
550         }
551
552         return ir.OXXX, ""
553 }
554
555 // Code to resolve elided DOTs in embedded types.
556
557 // A dlist stores a pointer to a TFIELD Type embedded within
558 // a TSTRUCT or TINTER Type.
559 type dlist struct {
560         field *types.Field
561 }
562
563 // dotpath computes the unique shortest explicit selector path to fully qualify
564 // a selection expression x.f, where x is of type t and f is the symbol s.
565 // If no such path exists, dotpath returns nil.
566 // If there are multiple shortest paths to the same depth, ambig is true.
567 func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []dlist, ambig bool) {
568         // The embedding of types within structs imposes a tree structure onto
569         // types: structs parent the types they embed, and types parent their
570         // fields or methods. Our goal here is to find the shortest path to
571         // a field or method named s in the subtree rooted at t. To accomplish
572         // that, we iteratively perform depth-first searches of increasing depth
573         // until we either find the named field/method or exhaust the tree.
574         for d := 0; ; d++ {
575                 if d > len(dotlist) {
576                         dotlist = append(dotlist, dlist{})
577                 }
578                 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
579                         return dotlist[:d], false
580                 } else if c > 1 {
581                         return nil, true
582                 } else if !more {
583                         return nil, false
584                 }
585         }
586 }
587
588 func expand0(t *types.Type) {
589         u := t
590         if u.IsPtr() {
591                 u = u.Elem()
592         }
593
594         if u.IsInterface() {
595                 for _, f := range u.AllMethods().Slice() {
596                         if f.Sym.Uniq() {
597                                 continue
598                         }
599                         f.Sym.SetUniq(true)
600                         slist = append(slist, symlink{field: f})
601                 }
602
603                 return
604         }
605
606         u = types.ReceiverBaseType(t)
607         if u != nil {
608                 for _, f := range u.Methods().Slice() {
609                         if f.Sym.Uniq() {
610                                 continue
611                         }
612                         f.Sym.SetUniq(true)
613                         slist = append(slist, symlink{field: f})
614                 }
615         }
616 }
617
618 func expand1(t *types.Type, top bool) {
619         if t.Recur() {
620                 return
621         }
622         t.SetRecur(true)
623
624         if !top {
625                 expand0(t)
626         }
627
628         u := t
629         if u.IsPtr() {
630                 u = u.Elem()
631         }
632
633         if u.IsStruct() || u.IsInterface() {
634                 var fields *types.Fields
635                 if u.IsStruct() {
636                         fields = u.Fields()
637                 } else {
638                         fields = u.AllMethods()
639                 }
640                 for _, f := range fields.Slice() {
641                         if f.Embedded == 0 {
642                                 continue
643                         }
644                         if f.Sym == nil {
645                                 continue
646                         }
647                         expand1(f.Type, false)
648                 }
649         }
650
651         t.SetRecur(false)
652 }
653
654 func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) *types.Field {
655         if t == nil {
656                 return nil
657         }
658
659         var m *types.Field
660         path, _ := dotpath(s, t, &m, ignorecase)
661         if path == nil {
662                 return nil
663         }
664
665         if !m.IsMethod() {
666                 return nil
667         }
668
669         return m
670 }
671
672 // Implements reports whether t implements the interface iface. t can be
673 // an interface, a type parameter, or a concrete type.
674 func Implements(t, iface *types.Type) bool {
675         var missing, have *types.Field
676         var ptr int
677         return implements(t, iface, &missing, &have, &ptr)
678 }
679
680 // ImplementsExplain reports whether t implements the interface iface. t can be
681 // an interface, a type parameter, or a concrete type. If t does not implement
682 // iface, a non-empty string is returned explaining why.
683 func ImplementsExplain(t, iface *types.Type) string {
684         var missing, have *types.Field
685         var ptr int
686         if implements(t, iface, &missing, &have, &ptr) {
687                 return ""
688         }
689
690         if isptrto(t, types.TINTER) {
691                 return fmt.Sprintf("%v is pointer to interface, not interface", t)
692         } else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
693                 return fmt.Sprintf("%v does not implement %v (%v method is marked 'nointerface')", t, iface, missing.Sym)
694         } else if have != nil && have.Sym == missing.Sym {
695                 return fmt.Sprintf("%v does not implement %v (wrong type for %v method)\n"+
696                         "\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
697         } else if ptr != 0 {
698                 return fmt.Sprintf("%v does not implement %v (%v method has pointer receiver)", t, iface, missing.Sym)
699         } else if have != nil {
700                 return fmt.Sprintf("%v does not implement %v (missing %v method)\n"+
701                         "\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
702         }
703         return fmt.Sprintf("%v does not implement %v (missing %v method)", t, iface, missing.Sym)
704 }
705
706 // implements reports whether t implements the interface iface. t can be
707 // an interface, a type parameter, or a concrete type. If implements returns
708 // false, it stores a method of iface that is not implemented in *m. If the
709 // method name matches but the type is wrong, it additionally stores the type
710 // of the method (on t) in *samename.
711 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
712         t0 := t
713         if t == nil {
714                 return false
715         }
716
717         if t.IsInterface() {
718                 i := 0
719                 tms := t.AllMethods().Slice()
720                 for _, im := range iface.AllMethods().Slice() {
721                         for i < len(tms) && tms[i].Sym != im.Sym {
722                                 i++
723                         }
724                         if i == len(tms) {
725                                 *m = im
726                                 *samename = nil
727                                 *ptr = 0
728                                 return false
729                         }
730                         tm := tms[i]
731                         if !types.Identical(tm.Type, im.Type) {
732                                 *m = im
733                                 *samename = tm
734                                 *ptr = 0
735                                 return false
736                         }
737                 }
738
739                 return true
740         }
741
742         t = types.ReceiverBaseType(t)
743         var tms []*types.Field
744         if t != nil {
745                 CalcMethods(t)
746                 tms = t.AllMethods().Slice()
747         }
748         i := 0
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 = ifacelookdot(im.Sym, t, true)
756                         *ptr = 0
757                         return false
758                 }
759                 tm := tms[i]
760                 if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
761                         *m = im
762                         *samename = tm
763                         *ptr = 0
764                         return false
765                 }
766                 followptr := tm.Embedded == 2
767
768                 // if pointer receiver in method,
769                 // the method does not exist for value types.
770                 rcvr := tm.Type.Recv().Type
771                 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !types.IsInterfaceMethod(tm.Type) {
772                         if false && base.Flag.LowerR != 0 {
773                                 base.Errorf("interface pointer mismatch")
774                         }
775
776                         *m = im
777                         *samename = nil
778                         *ptr = 1
779                         return false
780                 }
781         }
782
783         return true
784 }
785
786 func isptrto(t *types.Type, et types.Kind) bool {
787         if t == nil {
788                 return false
789         }
790         if !t.IsPtr() {
791                 return false
792         }
793         t = t.Elem()
794         if t == nil {
795                 return false
796         }
797         if t.Kind() != et {
798                 return false
799         }
800         return true
801 }
802
803 // lookdot0 returns the number of fields or methods named s associated
804 // with Type t. If exactly one exists, it will be returned in *save
805 // (if save is not nil).
806 func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
807         u := t
808         if u.IsPtr() {
809                 u = u.Elem()
810         }
811
812         c := 0
813         if u.IsStruct() || u.IsInterface() {
814                 var fields *types.Fields
815                 if u.IsStruct() {
816                         fields = u.Fields()
817                 } else {
818                         fields = u.AllMethods()
819                 }
820                 for _, f := range fields.Slice() {
821                         if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
822                                 if save != nil {
823                                         *save = f
824                                 }
825                                 c++
826                         }
827                 }
828         }
829
830         u = t
831         if t.Sym() != nil && t.IsPtr() && !t.Elem().IsPtr() {
832                 // If t is a defined pointer type, then x.m is shorthand for (*x).m.
833                 u = t.Elem()
834         }
835         u = types.ReceiverBaseType(u)
836         if u != nil {
837                 for _, f := range u.Methods().Slice() {
838                         if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
839                                 if save != nil {
840                                         *save = f
841                                 }
842                                 c++
843                         }
844                 }
845         }
846
847         return c
848 }
849
850 var slist []symlink
851
852 // Code to help generate trampoline functions for methods on embedded
853 // types. These are approx the same as the corresponding AddImplicitDots
854 // routines except that they expect to be called with unique tasks and
855 // they return the actual methods.
856
857 type symlink struct {
858         field *types.Field
859 }