diff --git a/errcheck/embedded_walker.go b/errcheck/embedded_walker.go index 3b31925..dff3917 100644 --- a/errcheck/embedded_walker.go +++ b/errcheck/embedded_walker.go @@ -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) @@ -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 } } diff --git a/testdata/embedded_interface.go b/testdata/embedded_interface.go new file mode 100644 index 0000000..5618748 --- /dev/null +++ b/testdata/embedded_interface.go @@ -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() +} \ No newline at end of file