diff --git a/go/internal/gcimporter/gcimporter_test.go b/go/internal/gcimporter/gcimporter_test.go index 6baab0128f..4e992af76b 100644 --- a/go/internal/gcimporter/gcimporter_test.go +++ b/go/internal/gcimporter/gcimporter_test.go @@ -587,6 +587,37 @@ func TestIssue25301(t *testing.T) { compileAndImportPkg(t, "issue25301") } +func TestIssue51836(t *testing.T) { + testenv.NeedsGo1Point(t, 18) // requires generics + + // This package only handles gc export data. + needsCompiler(t, "gc") + + // On windows, we have to set the -D option for the compiler to avoid having a drive + // letter and an illegal ':' in the import path - just skip it (see also issue #3483). + if runtime.GOOS == "windows" { + t.Skip("avoid dealing with relative paths/drive letters on windows") + } + + tmpdir := mktmpdir(t) + defer os.RemoveAll(tmpdir) + testoutdir := filepath.Join(tmpdir, "testdata") + + dir := filepath.Join("testdata", "issue51836") + // Following the pattern of TestIssue13898, aa.go needs to be compiled from + // the output directory. We pass the full path to compile() so that we don't + // have to copy the file to that directory. + bpath, err := filepath.Abs(filepath.Join(dir, "aa.go")) + if err != nil { + t.Fatal(err) + } + compile(t, dir, "a.go", testoutdir) + compile(t, testoutdir, bpath, testoutdir) + + // import must succeed (test for issue at hand) + _ = importPkg(t, "./testdata/aa", tmpdir) +} + func importPkg(t *testing.T, path, srcDir string) *types.Package { pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil) if err != nil { diff --git a/go/internal/gcimporter/iimport.go b/go/internal/gcimporter/iimport.go index 1d5650ae4e..28b91b8656 100644 --- a/go/internal/gcimporter/iimport.go +++ b/go/internal/gcimporter/iimport.go @@ -53,7 +53,7 @@ const ( ) type ident struct { - pkg string + pkg *types.Package name string } @@ -463,7 +463,7 @@ func (r *importReader) obj(name string) { // To handle recursive references to the typeparam within its // bound, save the partial type in tparamIndex before reading the bounds. - id := ident{r.currPkg.Name(), name} + id := ident{r.currPkg, name} r.p.tparamIndex[id] = t var implicit bool if r.p.version >= iexportVersionGo1_18 { @@ -779,7 +779,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) { errorf("unexpected type param type") } pkg, name := r.qualifiedIdent() - id := ident{pkg.Name(), name} + id := ident{pkg, name} if t, ok := r.p.tparamIndex[id]; ok { // We're already in the process of importing this typeparam. return t diff --git a/go/internal/gcimporter/testdata/issue51836/a.go b/go/internal/gcimporter/testdata/issue51836/a.go new file mode 100644 index 0000000000..e9223c9aa8 --- /dev/null +++ b/go/internal/gcimporter/testdata/issue51836/a.go @@ -0,0 +1,8 @@ +// Copyright 2022 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 + +type T[K any] struct { +} diff --git a/go/internal/gcimporter/testdata/issue51836/aa.go b/go/internal/gcimporter/testdata/issue51836/aa.go new file mode 100644 index 0000000000..d774be282e --- /dev/null +++ b/go/internal/gcimporter/testdata/issue51836/aa.go @@ -0,0 +1,13 @@ +// Copyright 2022 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 + +import ( + "./a" +) + +type T[K any] struct { + t a.T[K] +}