]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: print type parameters for Alias tyoes
authorRobert Griesemer <gri@golang.org>
Mon, 23 Sep 2024 17:46:41 +0000 (10:46 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 24 Sep 2024 17:44:11 +0000 (17:44 +0000)
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>

src/cmd/compile/internal/types2/check_test.go
src/cmd/compile/internal/types2/object.go
src/cmd/compile/internal/types2/object_test.go
src/cmd/compile/internal/types2/typestring.go
src/go/types/check_test.go
src/go/types/object.go
src/go/types/object_test.go
src/go/types/typestring.go

index 8b7b5316f04a842be5d3f24516eb92e063f43b84..8f537f912099f5724fc69c231c87646f1f50e24f 100644 (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
index d29c9a3df6766552f0ebb762e07338d1d99f2d6d..627b8b307418dff4e851d4eeae1c6d65fde1572c 100644 (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())
                        }
index 7e84d5296663c03da8da15a79c2c00d4616e4b5f..429f463bf7054b7b5caf15156e76f333b3f3a671 100644 (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)
index 7db86a70f1c3ba0bbfb0901851102e5606a7592c..36f90b673532f1aace1d2d2c69ca49349b37e066 100644 (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?
index 6c523b5d9ce848cb2edb62a4edd4f881c9985c16..be55616974601ebcf2d71e1bfe44b7842910eaad 100644 (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
index 06d5fbe5116febeb05412313ec01b6cac05c9650..9cd18e30150a1ae54c78bdbfaaf6cb23b70677ed 100644 (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())
                        }
index 43ff5b35e5cffa735b807d48b2ec88cafdc18d71..1a3f223e09f20627441e6cef69051b6b54f05b4c 100644 (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")
                        }
 
index 54f06138adc624efd772272ded446f09115270ae..3d6768db990e7f712e4db40cada40617e5f74a8e 100644 (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?