Skip to content

Commit

Permalink
Merge pull request #213 from kisielk/embedded-nil
Browse files Browse the repository at this point in the history
Handle embedded nil interfaces.
  • Loading branch information
kisielk authored May 20, 2022
2 parents e62617a + ab13fbe commit 98d3f84
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
7 changes: 3 additions & 4 deletions errcheck/embedded_walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ func walkThroughEmbeddedInterfaces(sel *types.Selection) ([]types.Type, bool) {
// define the method, add it to our list, and loop.
namedInterfaceT, ok := getEmbeddedInterfaceDefiningMethod(interfaceT, fn)
if !ok {
// This should be impossible as long as we type-checked: either the
// interface or one of its embedded ones must implement the method...
panic(fmt.Sprintf("either %v or one of its embedded interfaces must implement %v", currentT, fn))
// Returned a nil interface, we are done.
break
}
result = append(result, namedInterfaceT)
interfaceT = namedInterfaceT.Underlying().(*types.Interface)
Expand All @@ -102,7 +101,7 @@ func getTypeAtFieldIndex(startingAt types.Type, fieldIndex int) types.Type {
func getEmbeddedInterfaceDefiningMethod(interfaceT *types.Interface, fn *types.Func) (*types.Named, bool) {
for i := 0; i < interfaceT.NumEmbeddeds(); i++ {
embedded := interfaceT.Embedded(i)
if definesMethod(embedded.Underlying().(*types.Interface), fn) {
if embedded != nil && definesMethod(embedded.Underlying().(*types.Interface), fn) {
return embedded, true
}
}
Expand Down
18 changes: 18 additions & 0 deletions testdata/embedded_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func embeddedInterface() {
t := A(T{})
t.X()
}

type T struct{}

func (t T) X() {}

type A interface {
B // embeded
}

type B = interface { // B is not a defined type
X()
}

0 comments on commit 98d3f84

Please sign in to comment.