|
5 | 5 | package types2_test
|
6 | 6 |
|
7 | 7 | import (
|
| 8 | + "fmt" |
8 | 9 | "internal/testenv"
|
9 | 10 | "strings"
|
10 | 11 | "testing"
|
@@ -79,69 +80,72 @@ func TestEmbeddedMethod(t *testing.T) {
|
79 | 80 | }
|
80 | 81 |
|
81 | 82 | 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 |
85 | 87 | }{
|
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}, |
87 | 89 |
|
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}, |
90 | 92 |
|
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}, |
96 | 98 |
|
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}, |
99 | 102 |
|
100 |
| - {"var v int", "v", "var p.v int"}, |
| 103 | + {"var v int", "v", "var p.v int", false}, |
101 | 104 |
|
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}, |
106 | 109 | }
|
107 | 110 |
|
108 | 111 | func TestObjectString(t *testing.T) {
|
109 | 112 | testenv.MustHaveGoBuild(t)
|
110 | 113 |
|
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 | + } |
118 | 119 |
|
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]) |
135 | 142 | }
|
136 |
| - } else { |
137 |
| - t.Errorf("%s: %s has no type parameters", test.src, names[0]) |
138 |
| - continue |
139 | 143 | }
|
140 |
| - } |
141 | 144 |
|
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 | + }) |
145 | 149 | }
|
146 | 150 | }
|
147 | 151 |
|
|
0 commit comments