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