From 5e9beacd7719ae7c43fabd197739886eeb75bcf2 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 28 May 2015 12:59:43 -0700 Subject: [PATCH] go/types: fix error message for embedded non-interface types in interfaces Backport of https://go-review.googlesource.com/#/c/10466/ . Change-Id: Ib88a9707ea8ad6e2dbfaeb2edeb586a968abd508 Reviewed-on: https://go-review.googlesource.com/10468 Reviewed-by: Alan Donovan --- go/types/testdata/issues.src | 24 ++++++++++++++++++++++++ go/types/typexpr.go | 18 ++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/go/types/testdata/issues.src b/go/types/testdata/issues.src index d08e0fd8..595a6342 100644 --- a/go/types/testdata/issues.src +++ b/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/go/types/typexpr.go b/go/types/typexpr.go index 8c4b679a..c783bb6c 100644 --- a/go/types/typexpr.go +++ b/go/types/typexpr.go @@ -526,20 +526,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 }