1
0
mirror of https://github.com/golang/go synced 2024-11-14 17:30:29 -07:00

go/types, types2: print type parameters for Alias tyoes

Like for Named types, print type parameters for Alias types.

Add test case for Alias object string to existing test.
To make the test work, factor out the mechanism to set
GOEXPERIMENT=aliastypeparams at test time and use it
for this test as well.

No test case for un-instantiated generic type Alias type
string: there's no existing test framework, the code is
identical as for Named types, and these strings only appear
in tracing output. Tested manually.

Change-Id: I476d04d0b6a7c18b79be1d34a9e3e072941df83f
Reviewed-on: https://go-review.googlesource.com/c/go/+/615195
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Robert Griesemer 2024-09-23 10:46:41 -07:00 committed by Gopher Robot
parent 43cf73186b
commit e3cbda934c
8 changed files with 52 additions and 20 deletions

View File

@ -181,15 +181,9 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, colDelta uin
t.Fatal(err)
}
exp, err := buildcfg.ParseGOEXPERIMENT(runtime.GOOS, runtime.GOARCH, goexperiment)
if err != nil {
t.Fatal(err)
if goexperiment != "" {
defer setGOEXPERIMENT(goexperiment)()
}
old := buildcfg.Experiment
defer func() {
buildcfg.Experiment = old
}()
buildcfg.Experiment = *exp
// By default, gotypesalias is not set.
if gotypesalias != "" {
@ -324,6 +318,22 @@ func boolFieldAddr(conf *Config, name string) *bool {
return (*bool)(v.FieldByName(name).Addr().UnsafePointer())
}
// setGOEXPERIMENT overwrites the existing buildcfg.Experiment with a new one
// based on the provided goexperiment string. Calling the result function
// (typically via defer), reverts buildcfg.Experiment to the prior value.
// For testing use, only.
func setGOEXPERIMENT(goexperiment string) func() {
exp, err := buildcfg.ParseGOEXPERIMENT(runtime.GOOS, runtime.GOARCH, goexperiment)
if err != nil {
panic(err)
}
old := buildcfg.Experiment
buildcfg.Experiment = *exp
return func() {
buildcfg.Experiment = old
}
}
// TestManual is for manual testing of a package - either provided
// as a list of filenames belonging to the package, or a directory
// name containing the package files - after the test arguments

View File

@ -566,7 +566,7 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
// Don't print anything more for basic types since there's
// no more information.
return
case *Named:
case genericType:
if t.TypeParams().Len() > 0 {
newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
}

View File

@ -83,7 +83,7 @@ var testObjects = []struct {
src string
obj string
want string
alias bool // needs materialized aliases
alias bool // needs materialized (and possibly generic) aliases
}{
{"import \"io\"; var r io.Reader", "r", "var p.r io.Reader", false},
@ -99,6 +99,7 @@ var testObjects = []struct {
{"type t = struct{f int}", "t", "type p.t = struct{f int}", false},
{"type t = func(int)", "t", "type p.t = func(int)", false},
{"type A = B; type B = int", "A", "type p.A = p.B", true},
{"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}", true}, // requires GOEXPERIMENT=aliastypeparams
{"var v int", "v", "var p.v int", false},
@ -113,6 +114,9 @@ func TestObjectString(t *testing.T) {
for i, test := range testObjects {
t.Run(fmt.Sprint(i), func(t *testing.T) {
if test.alias {
defer setGOEXPERIMENT("aliastypeparams")()
}
src := "package p; " + test.src
conf := Config{Error: func(error) {}, Importer: defaultImporter(), EnableAlias: test.alias}
pkg, err := typecheck(src, &conf, nil)

View File

@ -338,6 +338,9 @@ func (w *typeWriter) typ(typ Type) {
if list := t.targs.list(); len(list) != 0 {
// instantiated type
w.typeList(list)
} else if w.ctxt == nil && t.TypeParams().Len() != 0 { // For type hashing, don't need to format the TypeParams
// parameterized type
w.tParamList(t.TypeParams().list())
}
if w.ctxt != nil {
// TODO(gri) do we need to print the alias type name, too?

View File

@ -196,15 +196,9 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, manual bool,
t.Fatal(err)
}
exp, err := buildcfg.ParseGOEXPERIMENT(runtime.GOOS, runtime.GOARCH, goexperiment)
if err != nil {
t.Fatal(err)
if goexperiment != "" {
defer setGOEXPERIMENT(goexperiment)()
}
old := buildcfg.Experiment
defer func() {
buildcfg.Experiment = old
}()
buildcfg.Experiment = *exp
// By default, gotypesalias is not set.
if gotypesalias != "" {
@ -352,6 +346,22 @@ func stringFieldAddr(conf *Config, name string) *string {
return (*string)(v.FieldByName(name).Addr().UnsafePointer())
}
// setGOEXPERIMENT overwrites the existing buildcfg.Experiment with a new one
// based on the provided goexperiment string. Calling the result function
// (typically via defer), reverts buildcfg.Experiment to the prior value.
// For testing use, only.
func setGOEXPERIMENT(goexperiment string) func() {
exp, err := buildcfg.ParseGOEXPERIMENT(runtime.GOOS, runtime.GOARCH, goexperiment)
if err != nil {
panic(err)
}
old := buildcfg.Experiment
buildcfg.Experiment = *exp
return func() {
buildcfg.Experiment = old
}
}
// TestManual is for manual testing of a package - either provided
// as a list of filenames belonging to the package, or a directory
// name containing the package files - after the test arguments

View File

@ -569,7 +569,7 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
// Don't print anything more for basic types since there's
// no more information.
return
case *Named:
case genericType:
if t.TypeParams().Len() > 0 {
newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
}

View File

@ -83,7 +83,7 @@ var testObjects = []struct {
src string
obj string
want string
alias bool // needs materialized aliases
alias bool // needs materialized (and possibly generic) aliases
}{
{"import \"io\"; var r io.Reader", "r", "var p.r io.Reader", false},
@ -99,6 +99,7 @@ var testObjects = []struct {
{"type t = struct{f int}", "t", "type p.t = struct{f int}", false},
{"type t = func(int)", "t", "type p.t = func(int)", false},
{"type A = B; type B = int", "A", "type p.A = p.B", true},
{"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}", true}, // requires GOEXPERIMENT=aliastypeparams
{"var v int", "v", "var p.v int", false},
@ -114,6 +115,7 @@ func TestObjectString(t *testing.T) {
for i, test := range testObjects {
t.Run(fmt.Sprint(i), func(t *testing.T) {
if test.alias {
defer setGOEXPERIMENT("aliastypeparams")()
t.Setenv("GODEBUG", "gotypesalias=1")
}

View File

@ -341,6 +341,9 @@ func (w *typeWriter) typ(typ Type) {
if list := t.targs.list(); len(list) != 0 {
// instantiated type
w.typeList(list)
} else if w.ctxt == nil && t.TypeParams().Len() != 0 { // For type hashing, don't need to format the TypeParams
// parameterized type
w.tParamList(t.TypeParams().list())
}
if w.ctxt != nil {
// TODO(gri) do we need to print the alias type name, too?