зеркало из https://github.com/golang/tools.git
internal/gcimporter: copy over ureader changes
Copy over the ureader.go changes from GOROOT's go/internal/gcimporter. Adds a test that goes through gc export data. Updates golang/go#68778 Change-Id: Ie4b91dfdb1ab9f952631a34c3691dc84be8831a7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/609317 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Родитель
09886e004e
Коммит
2db563b1a3
|
@ -956,6 +956,67 @@ func TestIssue58296(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIssueAliases(t *testing.T) {
|
||||
// This package only handles gc export data.
|
||||
testenv.NeedsGo1Point(t, 24)
|
||||
needsCompiler(t, "gc")
|
||||
testenv.NeedsGoBuild(t) // to find stdlib export data in the build cache
|
||||
testenv.NeedsGoExperiment(t, "aliastypeparams")
|
||||
|
||||
t.Setenv("GODEBUG", fmt.Sprintf("gotypesalias=%d", 1))
|
||||
|
||||
tmpdir := mktmpdir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
testoutdir := filepath.Join(tmpdir, "testdata")
|
||||
|
||||
apkg := filepath.Join(testoutdir, "a")
|
||||
bpkg := filepath.Join(testoutdir, "b")
|
||||
cpkg := filepath.Join(testoutdir, "c")
|
||||
|
||||
// compile a, b and c into gc export data.
|
||||
srcdir := filepath.Join("testdata", "aliases")
|
||||
compilePkg(t, filepath.Join(srcdir, "a"), "a.go", testoutdir, nil, apkg)
|
||||
compilePkg(t, filepath.Join(srcdir, "b"), "b.go", testoutdir, map[string]string{apkg: filepath.Join(testoutdir, "a.o")}, bpkg)
|
||||
compilePkg(t, filepath.Join(srcdir, "c"), "c.go", testoutdir,
|
||||
map[string]string{apkg: filepath.Join(testoutdir, "a.o"), bpkg: filepath.Join(testoutdir, "b.o")},
|
||||
cpkg,
|
||||
)
|
||||
|
||||
// import c from gc export data using a and b.
|
||||
pkg, err := Import(map[string]*types.Package{
|
||||
apkg: types.NewPackage(apkg, "a"),
|
||||
bpkg: types.NewPackage(bpkg, "b"),
|
||||
}, "./c", testoutdir, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check c's objects and types.
|
||||
var objs []string
|
||||
for _, imp := range pkg.Scope().Names() {
|
||||
obj := pkg.Scope().Lookup(imp)
|
||||
s := fmt.Sprintf("%s : %s", obj.Name(), obj.Type())
|
||||
s = strings.ReplaceAll(s, testoutdir, "testdata")
|
||||
objs = append(objs, s)
|
||||
}
|
||||
sort.Strings(objs)
|
||||
|
||||
want := strings.Join([]string{
|
||||
"S : struct{F int}",
|
||||
"T : struct{F int}",
|
||||
"U : testdata/a.A[string]",
|
||||
"V : testdata/a.A[int]",
|
||||
"W : testdata/b.B[string]",
|
||||
"X : testdata/b.B[int]",
|
||||
"Y : testdata/c.c[string]",
|
||||
"Z : testdata/c.c[int]",
|
||||
"c : testdata/c.c",
|
||||
}, ",")
|
||||
if got := strings.Join(objs, ","); got != want {
|
||||
t.Errorf("got imports %v for package c. wanted %v", objs, want)
|
||||
}
|
||||
}
|
||||
|
||||
// apkg returns the package "a" prefixed by (as a package) testoutdir
|
||||
func apkg(testoutdir string) string {
|
||||
apkg := testoutdir + "/a"
|
||||
|
|
|
@ -517,8 +517,6 @@ type Chained = C[Named] // B[Named, A[Named]] = B[Named, *Named] = []*Named
|
|||
// This means that it can be loaded by go/importer or go/types.
|
||||
// This step is not supported, but it does give test coverage for stdlib.
|
||||
"goroot": func(t *testing.T) *types.Package {
|
||||
t.Skip("Fix bug in src/internal/gcimporter.IImportData for aliasType then reenable")
|
||||
|
||||
// Write indexed export data file contents.
|
||||
//
|
||||
// TODO(taking): Slightly unclear to what extent this step should be supported by go/importer.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2024 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 A[T any] = *T
|
||||
|
||||
type B = struct{ F int }
|
||||
|
||||
func F() B {
|
||||
type a[T any] = struct{ F T }
|
||||
return a[int]{}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2024 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 b
|
||||
|
||||
import "./a"
|
||||
|
||||
type B[S any] = struct {
|
||||
F a.A[[]S]
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2024 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 c
|
||||
|
||||
import (
|
||||
"./a"
|
||||
"./b"
|
||||
)
|
||||
|
||||
type c[V any] = struct {
|
||||
G b.B[[3]V]
|
||||
}
|
||||
|
||||
var S struct{ F int } = a.B{}
|
||||
var T struct{ F int } = a.F()
|
||||
|
||||
var U a.A[string] = (*string)(nil)
|
||||
var V a.A[int] = (*int)(nil)
|
||||
|
||||
var W b.B[string] = struct{ F *[]string }{}
|
||||
var X b.B[int] = struct{ F *[]int }{}
|
||||
|
||||
var Y c[string] = struct{ G struct{ F *[][3]string } }{}
|
||||
var Z c[int] = struct{ G struct{ F *[][3]int } }{}
|
|
@ -53,7 +53,6 @@ func (pr *pkgReader) later(fn func()) {
|
|||
// See cmd/compile/internal/noder.derivedInfo.
|
||||
type derivedInfo struct {
|
||||
idx pkgbits.Index
|
||||
needed bool
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/noder.typeInfo.
|
||||
|
@ -110,13 +109,17 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
|
|||
|
||||
r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
|
||||
pkg := r.pkg()
|
||||
r.Bool() // has init
|
||||
if r.Version().Has(pkgbits.HasInit) {
|
||||
r.Bool()
|
||||
}
|
||||
|
||||
for i, n := 0, r.Len(); i < n; i++ {
|
||||
// As if r.obj(), but avoiding the Scope.Lookup call,
|
||||
// to avoid eager loading of imports.
|
||||
r.Sync(pkgbits.SyncObject)
|
||||
if r.Version().Has(pkgbits.DerivedFuncInstance) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
r.p.objIdx(r.Reloc(pkgbits.RelocObj))
|
||||
assert(r.Len() == 0)
|
||||
}
|
||||
|
@ -165,7 +168,7 @@ type readerDict struct {
|
|||
// tparams is a slice of the constructed TypeParams for the element.
|
||||
tparams []*types.TypeParam
|
||||
|
||||
// devived is a slice of types derived from tparams, which may be
|
||||
// derived is a slice of types derived from tparams, which may be
|
||||
// instantiated while reading the current element.
|
||||
derived []derivedInfo
|
||||
derivedTypes []types.Type // lazily instantiated from derived
|
||||
|
@ -471,7 +474,9 @@ func (r *reader) param() *types.Var {
|
|||
func (r *reader) obj() (types.Object, []types.Type) {
|
||||
r.Sync(pkgbits.SyncObject)
|
||||
|
||||
if r.Version().Has(pkgbits.DerivedFuncInstance) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
|
||||
pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
|
||||
obj := pkgScope(pkg).Lookup(name)
|
||||
|
@ -525,8 +530,11 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
|||
|
||||
case pkgbits.ObjAlias:
|
||||
pos := r.pos()
|
||||
var tparams []*types.TypeParam
|
||||
if r.Version().Has(pkgbits.AliasTypeParamNames) {
|
||||
tparams = r.typeParamNames()
|
||||
}
|
||||
typ := r.typ()
|
||||
var tparams []*types.TypeParam // TODO(#68778): read type params once pkgbits.V2 is available.
|
||||
declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ, tparams))
|
||||
|
||||
case pkgbits.ObjConst:
|
||||
|
@ -633,7 +641,10 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
|||
dict.derived = make([]derivedInfo, r.Len())
|
||||
dict.derivedTypes = make([]types.Type, len(dict.derived))
|
||||
for i := range dict.derived {
|
||||
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
||||
dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)}
|
||||
if r.Version().Has(pkgbits.DerivedInfoNeeded) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
}
|
||||
|
||||
pr.retireReader(r)
|
||||
|
|
Загрузка…
Ссылка в новой задаче