Skip to content

Commit 98d3f84

Browse files
authored
Merge pull request #213 from kisielk/embedded-nil
Handle embedded nil interfaces.
2 parents e62617a + ab13fbe commit 98d3f84

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

errcheck/embedded_walker.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ func walkThroughEmbeddedInterfaces(sel *types.Selection) ([]types.Type, bool) {
7373
// define the method, add it to our list, and loop.
7474
namedInterfaceT, ok := getEmbeddedInterfaceDefiningMethod(interfaceT, fn)
7575
if !ok {
76-
// This should be impossible as long as we type-checked: either the
77-
// interface or one of its embedded ones must implement the method...
78-
panic(fmt.Sprintf("either %v or one of its embedded interfaces must implement %v", currentT, fn))
76+
// Returned a nil interface, we are done.
77+
break
7978
}
8079
result = append(result, namedInterfaceT)
8180
interfaceT = namedInterfaceT.Underlying().(*types.Interface)
@@ -102,7 +101,7 @@ func getTypeAtFieldIndex(startingAt types.Type, fieldIndex int) types.Type {
102101
func getEmbeddedInterfaceDefiningMethod(interfaceT *types.Interface, fn *types.Func) (*types.Named, bool) {
103102
for i := 0; i < interfaceT.NumEmbeddeds(); i++ {
104103
embedded := interfaceT.Embedded(i)
105-
if definesMethod(embedded.Underlying().(*types.Interface), fn) {
104+
if embedded != nil && definesMethod(embedded.Underlying().(*types.Interface), fn) {
106105
return embedded, true
107106
}
108107
}

testdata/embedded_interface.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
func embeddedInterface() {
4+
t := A(T{})
5+
t.X()
6+
}
7+
8+
type T struct{}
9+
10+
func (t T) X() {}
11+
12+
type A interface {
13+
B // embeded
14+
}
15+
16+
type B = interface { // B is not a defined type
17+
X()
18+
}

0 commit comments

Comments
 (0)