]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/typecheck/subr.go
56ff7a73179051c86ef2ba7d8743769491a7e5db
[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 map and dst is a pointer to corresponding hmap.
541         // This rule is needed for the implementation detail that
542         // go gc maps are implemented as a pointer to a hmap struct.
543         if src.Kind() == types.TMAP && dst.IsPtr() &&
544                 src.MapType().Hmap == dst.Elem() {
545                 return ir.OCONVNOP, ""
546         }
547
548         // 11. src is a slice and dst is an array or pointer-to-array.
549         // They must have same element type.
550         if src.IsSlice() {
551                 if dst.IsArray() && types.Identical(src.Elem(), dst.Elem()) {
552                         return ir.OSLICE2ARR, ""
553                 }
554                 if dst.IsPtr() && dst.Elem().IsArray() &&
555                         types.Identical(src.Elem(), dst.Elem().Elem()) {
556                         return ir.OSLICE2ARRPTR, ""
557                 }
558         }
559
560         return ir.OXXX, ""
561 }
562
563 // Code to resolve elided DOTs in embedded types.
564
565 // A dlist stores a pointer to a TFIELD Type embedded within
566 // a TSTRUCT or TINTER Type.
567 type dlist struct {
568         field *types.Field
569 }
570
571 // dotpath computes the unique shortest explicit selector path to fully qualify
572 // a selection expression x.f, where x is of type t and f is the symbol s.
573 // If no such path exists, dotpath returns nil.
574 // If there are multiple shortest paths to the same depth, ambig is true.
575 func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []dlist, ambig bool) {
576         // The embedding of types within structs imposes a tree structure onto
577         // types: structs parent the types they embed, and types parent their
578         // fields or methods. Our goal here is to find the shortest path to
579         // a field or method named s in the subtree rooted at t. To accomplish
580         // that, we iteratively perform depth-first searches of increasing depth
581         // until we either find the named field/method or exhaust the tree.
582         for d := 0; ; d++ {
583                 if d > len(dotlist) {
584                         dotlist = append(dotlist, dlist{})
585                 }
586                 if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
587                         return dotlist[:d], false
588                 } else if c > 1 {
589                         return nil, true
590                 } else if !more {
591                         return nil, false
592                 }
593         }
594 }
595
596 func expand0(t *types.Type) {
597         u := t
598         if u.IsPtr() {
599                 u = u.Elem()
600         }
601
602         if u.IsInterface() {
603                 for _, f := range u.AllMethods().Slice() {
604                         if f.Sym.Uniq() {
605                                 continue
606                         }
607                         f.Sym.SetUniq(true)
608                         slist = append(slist, symlink{field: f})
609                 }
610
611                 return
612         }
613
614         u = types.ReceiverBaseType(t)
615         if u != nil {
616                 for _, f := range u.Methods().Slice() {
617                         if f.Sym.Uniq() {
618                                 continue
619                         }
620                         f.Sym.SetUniq(true)
621                         slist = append(slist, symlink{field: f})
622                 }
623         }
624 }
625
626 func expand1(t *types.Type, top bool) {
627         if t.Recur() {
628                 return
629         }
630         t.SetRecur(true)
631
632         if !top {
633                 expand0(t)
634         }
635
636         u := t
637         if u.IsPtr() {
638                 u = u.Elem()
639         }
640
641         if u.IsStruct() || u.IsInterface() {
642                 var fields *types.Fields
643                 if u.IsStruct() {
644                         fields = u.Fields()
645                 } else {
646                         fields = u.AllMethods()
647                 }
648                 for _, f := range fields.Slice() {
649                         if f.Embedded == 0 {
650                                 continue
651                         }
652                         if f.Sym == nil {
653                                 continue
654                         }
655                         expand1(f.Type, false)
656                 }
657         }
658
659         t.SetRecur(false)
660 }
661
662 func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) *types.Field {
663         if t == nil {
664                 return nil
665         }
666
667         var m *types.Field
668         path, _ := dotpath(s, t, &m, ignorecase)
669         if path == nil {
670                 return nil
671         }
672
673         if !m.IsMethod() {
674                 return nil
675         }
676
677         return m
678 }
679
680 // Implements reports whether t implements the interface iface. t can be
681 // an interface, a type parameter, or a concrete type.
682 func Implements(t, iface *types.Type) bool {
683         var missing, have *types.Field
684         var ptr int
685         return implements(t, iface, &missing, &have, &ptr)
686 }
687
688 // ImplementsExplain reports whether t implements the interface iface. t can be
689 // an interface, a type parameter, or a concrete type. If t does not implement
690 // iface, a non-empty string is returned explaining why.
691 func ImplementsExplain(t, iface *types.Type) string {
692         var missing, have *types.Field
693         var ptr int
694         if implements(t, iface, &missing, &have, &ptr) {
695                 return ""
696         }
697
698         if isptrto(t, types.TINTER) {
699                 return fmt.Sprintf("%v is pointer to interface, not interface", t)
700         } else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
701                 return fmt.Sprintf("%v does not implement %v (%v method is marked 'nointerface')", t, iface, missing.Sym)
702         } else if have != nil && have.Sym == missing.Sym {
703                 return fmt.Sprintf("%v does not implement %v (wrong type for %v method)\n"+
704                         "\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
705         } else if ptr != 0 {
706                 return fmt.Sprintf("%v does not implement %v (%v method has pointer receiver)", t, iface, missing.Sym)
707         } else if have != nil {
708                 return fmt.Sprintf("%v does not implement %v (missing %v method)\n"+
709                         "\t\thave %v%S\n\t\twant %v%S", t, iface, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
710         }
711         return fmt.Sprintf("%v does not implement %v (missing %v method)", t, iface, missing.Sym)
712 }
713
714 // implements reports whether t implements the interface iface. t can be
715 // an interface, a type parameter, or a concrete type. If implements returns
716 // false, it stores a method of iface that is not implemented in *m. If the
717 // method name matches but the type is wrong, it additionally stores the type
718 // of the method (on t) in *samename.
719 func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool {
720         t0 := t
721         if t == nil {
722                 return false
723         }
724
725         if t.IsInterface() {
726                 i := 0
727                 tms := t.AllMethods().Slice()
728                 for _, im := range iface.AllMethods().Slice() {
729                         for i < len(tms) && tms[i].Sym != im.Sym {
730                                 i++
731                         }
732                         if i == len(tms) {
733                                 *m = im
734                                 *samename = nil
735                                 *ptr = 0
736                                 return false
737                         }
738                         tm := tms[i]
739                         if !types.Identical(tm.Type, im.Type) {
740                                 *m = im
741                                 *samename = tm
742                                 *ptr = 0
743                                 return false
744                         }
745                 }
746
747                 return true
748         }
749
750         t = types.ReceiverBaseType(t)
751         var tms []*types.Field
752         if t != nil {
753                 CalcMethods(t)
754                 tms = t.AllMethods().Slice()
755         }
756         i := 0
757         for _, im := range iface.AllMethods().Slice() {
758                 for i < len(tms) && tms[i].Sym != im.Sym {
759                         i++
760                 }
761                 if i == len(tms) {
762                         *m = im
763                         *samename = ifacelookdot(im.Sym, t, true)
764                         *ptr = 0
765                         return false
766                 }
767                 tm := tms[i]
768                 if tm.Nointerface() || !types.Identical(tm.Type, im.Type) {
769                         *m = im
770                         *samename = tm
771                         *ptr = 0
772                         return false
773                 }
774                 followptr := tm.Embedded == 2
775
776                 // if pointer receiver in method,
777                 // the method does not exist for value types.
778                 rcvr := tm.Type.Recv().Type
779                 if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !types.IsInterfaceMethod(tm.Type) {
780                         if false && base.Flag.LowerR != 0 {
781                                 base.Errorf("interface pointer mismatch")
782                         }
783
784                         *m = im
785                         *samename = nil
786                         *ptr = 1
787                         return false
788                 }
789         }
790
791         return true
792 }
793
794 func isptrto(t *types.Type, et types.Kind) bool {
795         if t == nil {
796                 return false
797         }
798         if !t.IsPtr() {
799                 return false
800         }
801         t = t.Elem()
802         if t == nil {
803                 return false
804         }
805         if t.Kind() != et {
806                 return false
807         }
808         return true
809 }
810
811 // lookdot0 returns the number of fields or methods named s associated
812 // with Type t. If exactly one exists, it will be returned in *save
813 // (if save is not nil).
814 func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int {
815         u := t
816         if u.IsPtr() {
817                 u = u.Elem()
818         }
819
820         c := 0
821         if u.IsStruct() || u.IsInterface() {
822                 var fields *types.Fields
823                 if u.IsStruct() {
824                         fields = u.Fields()
825                 } else {
826                         fields = u.AllMethods()
827                 }
828                 for _, f := range fields.Slice() {
829                         if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
830                                 if save != nil {
831                                         *save = f
832                                 }
833                                 c++
834                         }
835                 }
836         }
837
838         u = t
839         if t.Sym() != nil && t.IsPtr() && !t.Elem().IsPtr() {
840                 // If t is a defined pointer type, then x.m is shorthand for (*x).m.
841                 u = t.Elem()
842         }
843         u = types.ReceiverBaseType(u)
844         if u != nil {
845                 for _, f := range u.Methods().Slice() {
846                         if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
847                                 if save != nil {
848                                         *save = f
849                                 }
850                                 c++
851                         }
852                 }
853         }
854
855         return c
856 }
857
858 var slist []symlink
859
860 // Code to help generate trampoline functions for methods on embedded
861 // types. These are approx the same as the corresponding AddImplicitDots
862 // routines except that they expect to be called with unique tasks and
863 // they return the actual methods.
864
865 type symlink struct {
866         field *types.Field
867 }