diff --git a/go/types/resolve.go b/go/types/resolve.go index 0b3a77401f..f2f9f63275 100644 --- a/go/types/resolve.go +++ b/go/types/resolve.go @@ -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) } diff --git a/go/types/resolver_test.go b/go/types/resolver_test.go index ea49111924..ae4fa2bb42 100644 --- a/go/types/resolver_test.go +++ b/go/types/resolver_test.go @@ -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} diff --git a/go/types/testdata/decls0.src b/go/types/testdata/decls0.src index c0d7f51224..c487734917 100644 --- a/go/types/testdata/decls0.src +++ b/go/types/testdata/decls0.src @@ -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 diff --git a/go/types/testdata/decls1.src b/go/types/testdata/decls1.src index b3ad5ac28f..779cf87716 100644 --- a/go/types/testdata/decls1.src +++ b/go/types/testdata/decls1.src @@ -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) {} diff --git a/go/types/testdata/decls2a.src b/go/types/testdata/decls2a.src index c15ac917d8..7246f228b5 100644 --- a/go/types/testdata/decls2a.src +++ b/go/types/testdata/decls2a.src @@ -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() {} diff --git a/go/types/testdata/decls2b.src b/go/types/testdata/decls2b.src index c7f9ddf01a..a28c695ea7 100644 --- a/go/types/testdata/decls2b.src +++ b/go/types/testdata/decls2b.src @@ -25,4 +25,10 @@ func (t *T6) m1() int { func f() { var t *T6 t.m1() -} \ No newline at end of file +} + +// 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" */ () {}