Skip to content

Commit 61a3ee5

Browse files
adonovangopherbot
authored andcommitted
go/types: ObjectString: remove only 1 Alias for "type A = RHS"
As we migrate towards materialized Alias types, the ObjectString for a type A such as type A = B type B = int should be "type A = B", removing exactly one Alias constructor from the type of A. (The previous behavior was "type A = int".) I suspect the existing Alias.{Unalias,Underlying} API is inadequate and that we will need an Alias.RHS accessor that removes exactly one Alias. Other clients such as the import/ export packages will need it, because aliases are not isomorphic to defined types, in which, given type A B type B int the Underlying of A is indeed int. See #66559. Change-Id: I11a4aacbe6dbeeafc3aee31b3c096296b5970cd8 Reviewed-on: https://go-review.googlesource.com/c/go/+/574716 Auto-Submit: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 6ffbcd8 commit 61a3ee5

File tree

4 files changed

+112
-96
lines changed

4 files changed

+112
-96
lines changed

src/cmd/compile/internal/types2/object.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,14 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
542542
}
543543
if tname.IsAlias() {
544544
buf.WriteString(" =")
545+
if alias, ok := typ.(*Alias); ok { // materialized? (gotypesalias=1)
546+
typ = alias.fromRHS
547+
}
545548
} else if t, _ := typ.(*TypeParam); t != nil {
546549
typ = t.bound
547550
} else {
548551
// TODO(gri) should this be fromRHS for *Named?
552+
// (See discussion in #66559.)
549553
typ = under(typ)
550554
}
551555
}

src/cmd/compile/internal/types2/object_test.go

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package types2_test
66

77
import (
8+
"fmt"
89
"internal/testenv"
910
"strings"
1011
"testing"
@@ -79,69 +80,72 @@ func TestEmbeddedMethod(t *testing.T) {
7980
}
8081

8182
var testObjects = []struct {
82-
src string
83-
obj string
84-
want string
83+
src string
84+
obj string
85+
want string
86+
alias bool // needs materialized aliases
8587
}{
86-
{"import \"io\"; var r io.Reader", "r", "var p.r io.Reader"},
88+
{"import \"io\"; var r io.Reader", "r", "var p.r io.Reader", false},
8789

88-
{"const c = 1.2", "c", "const p.c untyped float"},
89-
{"const c float64 = 3.14", "c", "const p.c float64"},
90+
{"const c = 1.2", "c", "const p.c untyped float", false},
91+
{"const c float64 = 3.14", "c", "const p.c float64", false},
9092

91-
{"type t struct{f int}", "t", "type p.t struct{f int}"},
92-
{"type t func(int)", "t", "type p.t func(int)"},
93-
{"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}"},
94-
{"type t[P any] struct{f P}", "t.P", "type parameter P any"},
95-
{"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C"},
93+
{"type t struct{f int}", "t", "type p.t struct{f int}", false},
94+
{"type t func(int)", "t", "type p.t func(int)", false},
95+
{"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}", false},
96+
{"type t[P any] struct{f P}", "t.P", "type parameter P any", false},
97+
{"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C", false},
9698

97-
{"type t = struct{f int}", "t", "type p.t = struct{f int}"},
98-
{"type t = func(int)", "t", "type p.t = func(int)"},
99+
{"type t = struct{f int}", "t", "type p.t = struct{f int}", false},
100+
{"type t = func(int)", "t", "type p.t = func(int)", false},
101+
{"type A = B; type B = int", "A", "type p.A = p.B", true},
99102

100-
{"var v int", "v", "var p.v int"},
103+
{"var v int", "v", "var p.v int", false},
101104

102-
{"func f(int) string", "f", "func p.f(int) string"},
103-
{"func g[P any](x P){}", "g", "func p.g[P any](x P)"},
104-
{"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}"},
105-
{"", "any", "type any = interface{}"},
105+
{"func f(int) string", "f", "func p.f(int) string", false},
106+
{"func g[P any](x P){}", "g", "func p.g[P any](x P)", false},
107+
{"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}", false},
108+
{"", "any", "type any = interface{}", false},
106109
}
107110

108111
func TestObjectString(t *testing.T) {
109112
testenv.MustHaveGoBuild(t)
110113

111-
for _, test := range testObjects {
112-
src := "package p; " + test.src
113-
pkg, err := typecheck(src, nil, nil)
114-
if err != nil {
115-
t.Errorf("%s: %s", src, err)
116-
continue
117-
}
114+
for i, test := range testObjects {
115+
t.Run(fmt.Sprint(i), func(t *testing.T) {
116+
if test.alias {
117+
t.Setenv("GODEBUG", "gotypesalias=1")
118+
}
118119

119-
names := strings.Split(test.obj, ".")
120-
if len(names) != 1 && len(names) != 2 {
121-
t.Errorf("%s: invalid object path %s", test.src, test.obj)
122-
continue
123-
}
124-
_, obj := pkg.Scope().LookupParent(names[0], nopos)
125-
if obj == nil {
126-
t.Errorf("%s: %s not found", test.src, names[0])
127-
continue
128-
}
129-
if len(names) == 2 {
130-
if typ, ok := obj.Type().(interface{ TypeParams() *TypeParamList }); ok {
131-
obj = lookupTypeParamObj(typ.TypeParams(), names[1])
132-
if obj == nil {
133-
t.Errorf("%s: %s not found", test.src, test.obj)
134-
continue
120+
src := "package p; " + test.src
121+
pkg, err := typecheck(src, nil, nil)
122+
if err != nil {
123+
t.Fatalf("%s: %s", src, err)
124+
}
125+
126+
names := strings.Split(test.obj, ".")
127+
if len(names) != 1 && len(names) != 2 {
128+
t.Fatalf("%s: invalid object path %s", test.src, test.obj)
129+
}
130+
_, obj := pkg.Scope().LookupParent(names[0], nopos)
131+
if obj == nil {
132+
t.Fatalf("%s: %s not found", test.src, names[0])
133+
}
134+
if len(names) == 2 {
135+
if typ, ok := obj.Type().(interface{ TypeParams() *TypeParamList }); ok {
136+
obj = lookupTypeParamObj(typ.TypeParams(), names[1])
137+
if obj == nil {
138+
t.Fatalf("%s: %s not found", test.src, test.obj)
139+
}
140+
} else {
141+
t.Fatalf("%s: %s has no type parameters", test.src, names[0])
135142
}
136-
} else {
137-
t.Errorf("%s: %s has no type parameters", test.src, names[0])
138-
continue
139143
}
140-
}
141144

142-
if got := obj.String(); got != test.want {
143-
t.Errorf("%s: got %s, want %s", test.src, got, test.want)
144-
}
145+
if got := obj.String(); got != test.want {
146+
t.Errorf("%s: got %s, want %s", test.src, got, test.want)
147+
}
148+
})
145149
}
146150
}
147151

src/go/types/object.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/go/types/object_test.go

Lines changed: 52 additions & 48 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)