@@ -8,6 +8,11 @@ package types
88
99import "go/token"
1010
11+ // Internal use of LookupFieldOrMethod: If the obj result is a method
12+ // associated with a concrete (non-interface) type, the method's signature
13+ // may not be fully set up. Call Checker.objDecl(obj, nil) before accessing
14+ // the method's type.
15+
1116// LookupFieldOrMethod looks up a field or method with given package and name
1217// in T and returns the corresponding *Var or *Func, an index sequence, and a
1318// bool indicating if there were any pointer indirections on the path to the
@@ -35,19 +40,6 @@ import "go/token"
3540// the method's formal receiver base type, nor was the receiver addressable.
3641//
3742func LookupFieldOrMethod (T Type , addressable bool , pkg * Package , name string ) (obj Object , index []int , indirect bool ) {
38- return (* Checker )(nil ).lookupFieldOrMethod (T , addressable , pkg , name )
39- }
40-
41- // Internal use of Checker.lookupFieldOrMethod: If the obj result is a method
42- // associated with a concrete (non-interface) type, the method's signature
43- // may not be fully set up. Call Checker.objDecl(obj, nil) before accessing
44- // the method's type.
45- // TODO(gri) Now that we provide the *Checker, we can probably remove this
46- // caveat by calling Checker.objDecl from lookupFieldOrMethod. Investigate.
47-
48- // lookupFieldOrMethod is like the external version but completes interfaces
49- // as necessary.
50- func (check * Checker ) lookupFieldOrMethod (T Type , addressable bool , pkg * Package , name string ) (obj Object , index []int , indirect bool ) {
5143 // Methods cannot be associated to a named pointer type
5244 // (spec: "The type denoted by T is called the receiver base type;
5345 // it must not be a pointer or interface type and it must be declared
@@ -57,26 +49,25 @@ func (check *Checker) lookupFieldOrMethod(T Type, addressable bool, pkg *Package
5749 // not have found it for T (see also issue 8590).
5850 if t := asNamed (T ); t != nil {
5951 if p , _ := t .Underlying ().(* Pointer ); p != nil {
60- obj , index , indirect = check . rawLookupFieldOrMethod (p , false , pkg , name )
52+ obj , index , indirect = lookupFieldOrMethod (p , false , pkg , name )
6153 if _ , ok := obj .(* Func ); ok {
6254 return nil , nil , false
6355 }
6456 return
6557 }
6658 }
6759
68- return check . rawLookupFieldOrMethod (T , addressable , pkg , name )
60+ return lookupFieldOrMethod (T , addressable , pkg , name )
6961}
7062
7163// TODO(gri) The named type consolidation and seen maps below must be
7264// indexed by unique keys for a given type. Verify that named
7365// types always have only one representation (even when imported
7466// indirectly via different packages.)
7567
76- // rawLookupFieldOrMethod should only be called by lookupFieldOrMethod and missingMethod.
77- func ( check * Checker ) rawLookupFieldOrMethod (T Type , addressable bool , pkg * Package , name string ) (obj Object , index []int , indirect bool ) {
68+ // lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
69+ func lookupFieldOrMethod (T Type , addressable bool , pkg * Package , name string ) (obj Object , index []int , indirect bool ) {
7870 // WARNING: The code in this function is extremely subtle - do not modify casually!
79- // This function and NewMethodSet should be kept in sync.
8071
8172 if name == "_" {
8273 return // blank fields/methods are never found
@@ -226,7 +217,7 @@ func (check *Checker) rawLookupFieldOrMethod(T Type, addressable bool, pkg *Pack
226217 return
227218 }
228219
229- current = check . consolidateMultiples (next )
220+ current = consolidateMultiples (next )
230221 }
231222
232223 return nil , nil , false // not found
@@ -243,15 +234,15 @@ type embeddedType struct {
243234// consolidateMultiples collects multiple list entries with the same type
244235// into a single entry marked as containing multiples. The result is the
245236// consolidated list.
246- func ( check * Checker ) consolidateMultiples (list []embeddedType ) []embeddedType {
237+ func consolidateMultiples (list []embeddedType ) []embeddedType {
247238 if len (list ) <= 1 {
248239 return list // at most one entry - nothing to do
249240 }
250241
251242 n := 0 // number of entries w/ unique type
252243 prev := make (map [Type ]int ) // index at which type was previously seen
253244 for _ , e := range list {
254- if i , found := check . lookupType (prev , e .typ ); found {
245+ if i , found := lookupType (prev , e .typ ); found {
255246 list [i ].multiples = true
256247 // ignore this entry
257248 } else {
@@ -263,14 +254,14 @@ func (check *Checker) consolidateMultiples(list []embeddedType) []embeddedType {
263254 return list [:n ]
264255}
265256
266- func ( check * Checker ) lookupType (m map [Type ]int , typ Type ) (int , bool ) {
257+ func lookupType (m map [Type ]int , typ Type ) (int , bool ) {
267258 // fast path: maybe the types are equal
268259 if i , found := m [typ ]; found {
269260 return i , true
270261 }
271262
272263 for t , i := range m {
273- if check . identical (t , typ ) {
264+ if Identical (t , typ ) {
274265 return i , true
275266 }
276267 }
@@ -336,7 +327,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
336327 // to see if they can be made to match.
337328 // TODO(gri) is this always correct? what about type bounds?
338329 // (Alternative is to rename/subst type parameters and compare.)
339- u := newUnifier (check , true )
330+ u := newUnifier (true )
340331 u .x .init (ftyp .tparams )
341332 if ! u .unify (ftyp , mtyp ) {
342333 return m , f
@@ -351,12 +342,12 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
351342 Vn := asNamed (Vd )
352343 for _ , m := range T .typeSet ().methods {
353344 // TODO(gri) should this be calling lookupFieldOrMethod instead (and why not)?
354- obj , _ , _ := check . rawLookupFieldOrMethod (V , false , m .pkg , m .name )
345+ obj , _ , _ := lookupFieldOrMethod (V , false , m .pkg , m .name )
355346
356347 // Check if *V implements this method of T.
357348 if obj == nil {
358349 ptr := NewPointer (V )
359- obj , _ , _ = check . rawLookupFieldOrMethod (ptr , false , m .pkg , m .name )
350+ obj , _ , _ = lookupFieldOrMethod (ptr , false , m .pkg , m .name )
360351 if obj != nil {
361352 return m , obj .(* Func )
362353 }
@@ -412,7 +403,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
412403 // to see if they can be made to match.
413404 // TODO(gri) is this always correct? what about type bounds?
414405 // (Alternative is to rename/subst type parameters and compare.)
415- u := newUnifier (check , true )
406+ u := newUnifier (true )
416407 u .x .init (ftyp .rparams )
417408 if ! u .unify (ftyp , mtyp ) {
418409 return m , f
0 commit comments