diff --git a/src/go/go2go/rewrite.go b/src/go/go2go/rewrite.go index d72a5b7513..fb8564587d 100644 --- a/src/go/go2go/rewrite.go +++ b/src/go/go2go/rewrite.go @@ -648,6 +648,7 @@ func (t *translator) translateExpr(pe *ast.Expr) { } switch e := (*pe).(type) { case *ast.Ident: + t.translateIdent(pe) case *ast.Ellipsis: t.translateExpr(&e.Elt) case *ast.BasicLit: @@ -715,6 +716,38 @@ func (t *translator) translateExpr(pe *ast.Expr) { } } +// translateIdent translates a simple identifier from Go with +// contracts to Go 1. These are usually fine as is, but a reference +// to a non-generic name in another package may need a package qualifier. +func (t *translator) translateIdent(pe *ast.Expr) { + e := (*pe).(*ast.Ident) + obj := t.importer.info.ObjectOf(e) + if obj == nil { + return + } + if named, ok := obj.Type().(*types.Named); ok && len(named.TParams()) > 0 { + // A generic function that will be instantiated locally. + return + } + ipkg := obj.Pkg() + if ipkg == nil || ipkg == t.tpkg { + // We don't need a package qualifier if it's defined + // in the current package. + return + } + if obj.Parent() != ipkg.Scope() { + // We only need a package qualifier if it's defined in + // package scope. + return + } + + // Add package qualifier. + *pe = &ast.SelectorExpr{ + X: ast.NewIdent(ipkg.Name()), + Sel: e, + } +} + // translateSelectorExpr translates a selector expression // from Go with contracts to Go 1. func (t *translator) translateSelectorExpr(pe *ast.Expr) { diff --git a/test/gen/g037.dir/a.go2 b/test/gen/g037.dir/a.go2 new file mode 100644 index 0000000000..eb8030e744 --- /dev/null +++ b/test/gen/g037.dir/a.go2 @@ -0,0 +1,11 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package a + +func F() {} + +func G(type T)() { + F() +} diff --git a/test/gen/g037.dir/b.go2 b/test/gen/g037.dir/b.go2 new file mode 100644 index 0000000000..9d23eb2406 --- /dev/null +++ b/test/gen/g037.dir/b.go2 @@ -0,0 +1,11 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "./a" + +func main() { + a.G(int)() +} diff --git a/test/gen/g037.go2 b/test/gen/g037.go2 new file mode 100644 index 0000000000..4a7d9e185b --- /dev/null +++ b/test/gen/g037.go2 @@ -0,0 +1,7 @@ +// rundir + +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ignored