Skip to content

Commit cd6d225

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: added clarifying comments, removed TODO in lookup.go
Also, renamed lookupFieldOrMethod to lookupFieldOrMethodImpl to make a clearer distinction between this function and the exported version LookupFieldOrMethod. Except for the rename, all changes are to comments only. Change-Id: If7d1465c9cf659ea86bbbbcba8b95f16d2170fcc Reviewed-on: https://go-review.googlesource.com/c/go/+/473075 Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent cbb9cd0 commit cd6d225

File tree

2 files changed

+54
-24
lines changed

2 files changed

+54
-24
lines changed

src/cmd/compile/internal/types2/lookup.go

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
5555
// not have found it for T (see also go.dev/issue/8590).
5656
if t, _ := T.(*Named); t != nil {
5757
if p, _ := t.Underlying().(*Pointer); p != nil {
58-
obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name, false)
58+
obj, index, indirect = lookupFieldOrMethodImpl(p, false, pkg, name, false)
5959
if _, ok := obj.(*Func); ok {
6060
return nil, nil, false
6161
}
6262
return
6363
}
6464
}
6565

66-
obj, index, indirect = lookupFieldOrMethod(T, addressable, pkg, name, false)
66+
obj, index, indirect = lookupFieldOrMethodImpl(T, addressable, pkg, name, false)
6767

6868
// If we didn't find anything and if we have a type parameter with a core type,
6969
// see if there is a matching field (but not a method, those need to be declared
@@ -72,7 +72,7 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
7272
const enableTParamFieldLookup = false // see go.dev/issue/51576
7373
if enableTParamFieldLookup && obj == nil && isTypeParam(T) {
7474
if t := coreType(T); t != nil {
75-
obj, index, indirect = lookupFieldOrMethod(t, addressable, pkg, name, false)
75+
obj, index, indirect = lookupFieldOrMethodImpl(t, addressable, pkg, name, false)
7676
if _, ok := obj.(*Var); !ok {
7777
obj, index, indirect = nil, nil, false // accept fields (variables) only
7878
}
@@ -81,18 +81,33 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
8181
return
8282
}
8383

84-
// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
85-
// If foldCase is true, the lookup for methods will include looking for any method
86-
// which case-folds to the same as 'name' (used for giving helpful error messages).
84+
// lookupFieldOrMethodImpl is the implementation of LookupFieldOrMethod.
85+
// Notably, in contrast to LookupFieldOrMethod, it won't find struct fields
86+
// in base types of defined (*Named) pointer types T. For instance, given
87+
// the declaration:
88+
//
89+
// type T *struct{f int}
90+
//
91+
// lookupFieldOrMethodImpl won't find the field f in the defined (*Named) type T
92+
// (methods on T are not permitted in the first place).
93+
//
94+
// Thus, lookupFieldOrMethodImpl should only be called by LookupFieldOrMethod
95+
// and missingMethod (the latter doesn't care about struct fields).
96+
//
97+
// If foldCase is true, method names are considered equal if they are equal
98+
// with case folding.
8799
//
88100
// The resulting object may not be fully type-checked.
89-
func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) {
101+
func lookupFieldOrMethodImpl(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) {
90102
// WARNING: The code in this function is extremely subtle - do not modify casually!
91103

92104
if name == "_" {
93105
return // blank fields/methods are never found
94106
}
95107

108+
// Importantly, we must not call under before the call to deref below (nor
109+
// does deref call under), as doing so could incorrectly result in finding
110+
// methods of the pointer base type when T is a (*Named) pointer type.
96111
typ, isPtr := deref(T)
97112

98113
// *typ where typ is an interface (incl. a type parameter) has no methods.
@@ -356,14 +371,13 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
356371
}
357372
} else {
358373
for _, m = range methods {
359-
// TODO(gri) should this be calling LookupFieldOrMethod instead (and why not)?
360-
obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name, false)
374+
obj, _, _ := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
361375

362376
// check if m is on *V, or on V with case-folding
363377
if obj == nil {
364378
state = notFound
365379
// TODO(gri) Instead of NewPointer(V) below, can we just set the "addressable" argument?
366-
obj, _, _ = lookupFieldOrMethod(NewPointer(V), false, m.pkg, m.name, false)
380+
obj, _, _ = lookupFieldOrMethodImpl(NewPointer(V), false, m.pkg, m.name, false)
367381
if obj != nil {
368382
f, _ = obj.(*Func)
369383
if f != nil {
@@ -372,7 +386,7 @@ func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y
372386
// otherwise we found a field, keep state == notFound
373387
break
374388
}
375-
obj, _, _ = lookupFieldOrMethod(V, false, m.pkg, m.name, true /* fold case */)
389+
obj, _, _ = lookupFieldOrMethodImpl(V, false, m.pkg, m.name, true /* fold case */)
376390
if obj != nil {
377391
f, _ = obj.(*Func)
378392
if f != nil {
@@ -504,7 +518,8 @@ func (check *Checker) newAssertableTo(V, T Type, cause *string) bool {
504518
return check.implements(T, V, false, cause)
505519
}
506520

507-
// deref dereferences typ if it is a *Pointer and returns its base and true.
521+
// deref dereferences typ if it is a *Pointer (but not a *Named type
522+
// with an underlying pointer type!) and returns its base and true.
508523
// Otherwise it returns (typ, false).
509524
func deref(typ Type) (Type, bool) {
510525
if p, _ := typ.(*Pointer); p != nil {

src/go/types/lookup.go

Lines changed: 27 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)