From: Robert Griesemer Date: Thu, 28 May 2015 18:58:42 +0000 (-0700) Subject: go/types: fix error message for embedded non-interface types in interfaces X-Git-Tag: go1.5beta1~447 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ccc037699e2966b7c79ba84c67471cef5e67a3b8;p=gostls13.git go/types: fix error message for embedded non-interface types in interfaces Fixes #10979. Change-Id: Iac25645ba8181a56a75ddfcd29ff6d64c15c4f57 Reviewed-on: https://go-review.googlesource.com/10466 Reviewed-by: Alan Donovan --- diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src index d08e0fd878..595a6342b7 100644 --- a/src/go/types/testdata/issues.src +++ b/src/go/types/testdata/issues.src @@ -71,3 +71,27 @@ func issue9473(a []int, b ...int) { append_(f0(), f1()... /* ERROR cannot use */ ) append_(f0(), f2()... /* ERROR cannot use */ ) } + +// Check that embedding a non-interface type in an interface results in a good error message. +func issue10979() { + type _ interface { + int /* ERROR int is not an interface */ + } + type T struct{} + type _ interface { + T /* ERROR T is not an interface */ + } + type _ interface { + nosuchtype /* ERROR undeclared name: nosuchtype */ + } + type _ interface { + fmt /* ERROR Nosuchtype not declared by package fmt */ .Nosuchtype + } + type _ interface { + nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype + } + type I interface { + I /* ERROR I\.m \(value of type func\(I\)\) is not a type */ .m + m() + } +} diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index f4e4dcb040..3fc1574e80 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -525,20 +525,14 @@ func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, d for _, e := range embedded { pos := e.Pos() typ := check.typExpr(e, nil, path) + // Determine underlying embedded (possibly incomplete) type + // by following its forward chain. named, _ := typ.(*Named) - if named == nil { - if typ != Typ[Invalid] { - check.invalidAST(pos, "%s is not named type", typ) - } - continue - } - // determine underlying (possibly incomplete) type - // by following its forward chain - u := underlying(named) - embed, _ := u.(*Interface) + under := underlying(named) + embed, _ := under.(*Interface) if embed == nil { - if u != Typ[Invalid] { - check.errorf(pos, "%s is not an interface", named) + if typ != Typ[Invalid] { + check.errorf(pos, "%s is not an interface", typ) } continue }