go.tools/go.types: check for redeclarations across package files

Fixes golang/go#5506.

R=adonovan
CC=golang-dev
https://golang.org/cl/9600044
This commit is contained in:
Robert Griesemer 2013-05-20 14:29:57 -07:00
parent ad2dafcf8f
commit 08ee2985d7
6 changed files with 25 additions and 8 deletions

View File

@ -73,7 +73,8 @@ func (check *checker) resolve(importer Importer) (methods []*ast.FuncDecl) {
check.register(file.Name, pkg)
// insert top-level file objects in package scope
// (the parser took care of declaration errors)
// (the parser took care of declaration errors in a single file,
// but not across multiple files - hence we need to check again)
for _, decl := range file.Decls {
switch d := decl.(type) {
case *ast.BadDecl:
@ -91,13 +92,13 @@ func (check *checker) resolve(importer Importer) (methods []*ast.FuncDecl) {
if name.Name == "_" {
continue
}
pkg.scope.Insert(check.lookup(name))
check.declareObj(pkg.scope, nil, check.lookup(name), token.NoPos)
}
case *ast.TypeSpec:
if s.Name.Name == "_" {
continue
}
pkg.scope.Insert(check.lookup(s.Name))
check.declareObj(pkg.scope, nil, check.lookup(s.Name), token.NoPos)
default:
check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s)
}
@ -111,7 +112,7 @@ func (check *checker) resolve(importer Importer) (methods []*ast.FuncDecl) {
if d.Name.Name == "_" || d.Name.Name == "init" {
continue // blank (_) and init functions are inaccessible
}
pkg.scope.Insert(check.lookup(d.Name))
check.declareObj(pkg.scope, nil, check.lookup(d.Name), token.NoPos)
default:
check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
}

View File

@ -35,7 +35,7 @@ var sources = []string{
package p
import . "go/parser"
import "sync"
func g() Mode { return ImportsOnly }
func h() Mode { return ImportsOnly }
var _, x int = 1, 2
func init() {}
type T struct{ sync.Mutex; a, b, c int}

View File

@ -69,7 +69,12 @@ type (
Pi pi /* ERROR "not a type" */
a /* ERROR "illegal cycle" */ a
a /* ERROR "redeclared" */ int
// TODO(gri) For now we get double redeclaration errors if the redeclaration
// happens at the package level in the same file. This is because one check
// is done in the parser and the other one in the type checker. We cannot
// easily avoid this w/o losing the check or functionality. This will be
// fixed once all resolution is done in the type checker.
a /* ERROR "redeclared" */ /* ERROR "redeclared" */ int
// where the cycle error appears depends on the
// order in which declarations are processed

View File

@ -123,7 +123,6 @@ func (*T) m1() {}
func (x T) m2() {}
func (x *T) m3() {}
// Initialization functions
func init() {}
func /* ERROR "no arguments and no return values" */ init(int) {}

View File

@ -64,3 +64,9 @@ func (int /* ERROR "non-local type" */ ) m() {}
func ([ /* ERROR "expected" */ ]int) m() {}
func (time /* ERROR "expected" */ .Time) m() {}
func (x interface /* ERROR "expected" */ {}) m() {}
// Double declarations across package files
const c_double = 0
type t_double int
var v_double int
func f_double() {}

View File

@ -26,3 +26,9 @@ func f() {
var t *T6
t.m1()
}
// Double declarations across package files
const c_double /* ERROR "redeclared" */ = 0
type t_double /* ERROR "redeclared" */ int
var v_double /* ERROR "redeclared" */ int
func f_double /* ERROR "redeclared" */ () {}