diff --git a/go/types/labels.go b/go/types/labels.go index fe0319c8..d6ffc523 100644 --- a/go/types/labels.go +++ b/go/types/labels.go @@ -131,7 +131,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele case *ast.LabeledStmt: // declare non-blank label if name := s.Label.Name; name != "_" { - lbl := NewLabel(s.Label.Pos(), name) + lbl := NewLabel(s.Label.Pos(), check.pkg, name) if alt := all.Insert(lbl); alt != nil { check.softErrorf(lbl.pos, "label %s already declared", name) check.reportAltDecl(alt) diff --git a/go/types/object.go b/go/types/object.go index 4c2a8ca0..a495f85c 100644 --- a/go/types/object.go +++ b/go/types/object.go @@ -201,8 +201,8 @@ type Label struct { object } -func NewLabel(pos token.Pos, name string) *Label { - return &Label{object{pos: pos, name: name, typ: Typ[Invalid]}} +func NewLabel(pos token.Pos, pkg *Package, name string) *Label { + return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}} } // A Builtin represents a built-in function. diff --git a/go/types/stdlib_test.go b/go/types/stdlib_test.go index 44aef2f4..8a6a9bb2 100644 --- a/go/types/stdlib_test.go +++ b/go/types/stdlib_test.go @@ -174,8 +174,25 @@ func typecheck(t *testing.T, path string, filenames []string) { // typecheck package files var conf Config conf.Error = func(err error) { t.Error(err) } - conf.Check(path, fset, files, nil) + info := Info{Uses: make(map[*ast.Ident]Object)} + conf.Check(path, fset, files, &info) pkgCount++ + + // Perform checks of API invariants. + + // All Objects have a package, except predeclared ones. + errorError := Universe.Lookup("error").Type().Underlying().(*Interface).ExplicitMethod(0) // (error).Error + for id, obj := range info.Uses { + predeclared := obj == Universe.Lookup(obj.Name()) || obj == errorError + if predeclared == (obj.Pkg() != nil) { + posn := fset.Position(id.Pos()) + if predeclared { + t.Errorf("%s: predeclared object with package: %s", posn, obj) + } else { + t.Errorf("%s: user-defined object without package: %s", posn, obj) + } + } + } } // pkgFilenames returns the list of package filenames for the given directory.