Skip to content

Commit c642f18

Browse files
working on nesting types
1 parent e671c77 commit c642f18

File tree

7 files changed

+59
-38
lines changed

7 files changed

+59
-38
lines changed

compiler/decls.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,8 @@ func (fc *funcContext) newNamedTypeVarDecl(obj *types.TypeName) *Decl {
451451
func (fc *funcContext) newNamedTypeInstDecl(inst typeparams.Instance) (*Decl, error) {
452452
originType := inst.Object.Type().(*types.Named)
453453

454-
fc.typeResolver = typeparams.NewResolver(fc.pkgCtx.typesCtx, originType.TypeParams(), inst.TArgs)
454+
// TODO(grantnelson-wf): Need to handle nested type parameters instances.
455+
fc.typeResolver = typeparams.NewResolver(fc.pkgCtx.typesCtx, originType.TypeParams(), inst.TArgs, nil)
455456
defer func() { fc.typeResolver = nil }()
456457

457458
instanceType := originType

compiler/functions.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ func (fc *funcContext) nestedFunctionContext(info *analysis.FuncInfo, inst typep
4949
}
5050

5151
if sig.TypeParams().Len() > 0 {
52-
c.typeResolver = typeparams.NewResolver(c.pkgCtx.typesCtx, sig.TypeParams(), inst.TArgs)
52+
c.typeResolver = typeparams.NewResolver(c.pkgCtx.typesCtx, sig.TypeParams(), inst.TArgs, nil)
5353
} else if sig.RecvTypeParams().Len() > 0 {
54-
c.typeResolver = typeparams.NewResolver(c.pkgCtx.typesCtx, sig.RecvTypeParams(), inst.TArgs)
54+
c.typeResolver = typeparams.NewResolver(c.pkgCtx.typesCtx, sig.RecvTypeParams(), inst.TArgs, nil)
5555
}
5656
if c.objectNames == nil {
5757
c.objectNames = map[types.Object]string{}

compiler/internal/analysis/info.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (info *Info) newFuncInfoInstances(fd *ast.FuncDecl) []*FuncInfo {
127127
var resolver *typeparams.Resolver
128128
if sig, ok := obj.Type().(*types.Signature); ok {
129129
tp := typeparams.SignatureTypeParams(sig)
130-
resolver = typeparams.NewResolver(info.typeCtx, tp, inst.TArgs)
130+
resolver = typeparams.NewResolver(info.typeCtx, tp, inst.TArgs, nil)
131131
}
132132
fi := info.newFuncInfo(fd, inst.Object, inst.TArgs, resolver)
133133
funcInfos = append(funcInfos, fi)

compiler/internal/typeparams/collect.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ type Resolver struct {
1818

1919
// NewResolver creates a new Resolver with tParams entries mapping to tArgs
2020
// entries with the same index.
21-
func NewResolver(tc *types.Context, tParams *types.TypeParamList, tArgs []types.Type) *Resolver {
21+
func NewResolver(tc *types.Context, tParams *types.TypeParamList, tArgs []types.Type, parent *Resolver) *Resolver {
22+
var nest *subst.Subster
23+
if parent != nil {
24+
nest = parent.subster
25+
}
2226
r := &Resolver{
23-
subster: subst.New(tc, tParams, tArgs),
27+
subster: subst.New(tc, tParams, tArgs, nest),
2428
selMemo: map[typesutil.Selection]typesutil.Selection{},
2529
}
2630
return r
@@ -286,7 +290,7 @@ func (c *Collector) Scan(pkg *types.Package, files ...*ast.File) {
286290
tParams := SignatureTypeParams(typ)
287291
v := visitor{
288292
instances: c.Instances,
289-
resolver: NewResolver(c.TContext, tParams, inst.TArgs),
293+
resolver: NewResolver(c.TContext, tParams, inst.TArgs, nil),
290294
info: c.Info,
291295
}
292296
fmt.Printf("[Start] Signature: %s\n\t%v\n", inst.TypeString(), v.resolver) // TODO(grantnelson-wf): remove
@@ -297,7 +301,7 @@ func (c *Collector) Scan(pkg *types.Package, files ...*ast.File) {
297301
obj := typ.Obj()
298302
v := visitor{
299303
instances: c.Instances,
300-
resolver: NewResolver(c.TContext, typ.TypeParams(), inst.TArgs),
304+
resolver: NewResolver(c.TContext, typ.TypeParams(), inst.TArgs, nil),
301305
info: c.Info,
302306
}
303307
fmt.Printf("[Start] Named: %s\n", inst.TypeString()) // TODO(grantnelson-wf): remove

compiler/internal/typeparams/collect_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ func TestVisitor(t *testing.T) {
196196
types.NewContext(),
197197
lookupType("entry2").(*types.Signature).TypeParams(),
198198
[]types.Type{lookupType("B")},
199+
nil,
199200
),
200201
node: lookupDecl("entry2"),
201202
want: instancesInFunc(lookupType("B")),
@@ -205,6 +206,7 @@ func TestVisitor(t *testing.T) {
205206
types.NewContext(),
206207
lookupType("entry3.method").(*types.Signature).RecvTypeParams(),
207208
[]types.Type{lookupType("C")},
209+
nil,
208210
),
209211
node: lookupDecl("entry3.method"),
210212
want: append(
@@ -224,6 +226,7 @@ func TestVisitor(t *testing.T) {
224226
types.NewContext(),
225227
lookupType("entry3").(*types.Named).TypeParams(),
226228
[]types.Type{lookupType("D")},
229+
nil,
227230
),
228231
node: lookupDecl("entry3"),
229232
want: instancesInType(lookupType("D")),
@@ -492,7 +495,7 @@ func TestResolver_SubstituteSelection(t *testing.T) {
492495
info, pkg := f.Check("pkg/test", file)
493496

494497
method := srctesting.LookupObj(pkg, "g.Method").(*types.Func).Type().(*types.Signature)
495-
resolver := NewResolver(nil, method.RecvTypeParams(), []types.Type{srctesting.LookupObj(pkg, "x").Type()})
498+
resolver := NewResolver(nil, method.RecvTypeParams(), []types.Type{srctesting.LookupObj(pkg, "x").Type()}, nil)
496499

497500
if l := len(info.Selections); l != 1 {
498501
t.Fatalf("Got: %d selections. Want: 1", l)

internal/govendor/subst/export.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ func (s *Subster) Type(typ types.Type) types.Type {
5050
if s == nil {
5151
return typ
5252
}
53+
typ = s.impl.typ(typ)
5354
if s.nest != nil {
5455
typ = s.nest.Type(typ)
5556
}
56-
return s.impl.typ(typ)
57+
return typ
5758
}
5859

5960
// String gets a strings representation of the replacement for debugging.

internal/govendor/subst/export_test.go

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestNestedSubstInGenericFunction(t *testing.T) {
2525
`
2626

2727
fSet := token.NewFileSet()
28-
f, err := parser.ParseFile(fSet, "hello.go", source, 0)
28+
f, err := parser.ParseFile(fSet, `hello.go`, source, 0)
2929
if err != nil {
3030
t.Fatal(err)
3131
}
@@ -41,46 +41,59 @@ func TestNestedSubstInGenericFunction(t *testing.T) {
4141
args []string // type expressions of args for the named type
4242
}
4343

44-
for _, test := range []struct {
45-
nesting []namedType
46-
want string // expected underlying value after substitution
44+
for i, test := range []struct {
45+
nesting []namedType
46+
want string // expected underlying value after substitution
47+
substWant string // expected string value of the Subster
4748
}{
49+
// "Substituting types.Signatures with generic functions are currently unsupported."
50+
// since we should be getting back concrete functions from the type checker.
51+
//{
52+
// nesting: []namedType{
53+
// {name: `A`, args: []string{`int`}},
54+
// },
55+
//},
4856
{
4957
nesting: []namedType{
5058
{name: `A`, args: []string{`int`}},
59+
{name: `B`},
5160
},
52-
want: `struct{X int}`,
61+
want: `struct{X int}`,
62+
substWant: `{T->int}`,
5363
},
5464
{
5565
nesting: []namedType{
5666
{name: `A`, args: []string{`int`}},
57-
{name: `B`},
67+
{name: `C`, args: []string{`bool`}},
5868
},
59-
want: `struct{X int}`,
69+
want: `struct{X int; Y bool}`,
70+
substWant: `{T->int}:{U->bool}`,
6071
},
6172
{
6273
nesting: []namedType{
63-
{name: `A`, args: []string{`int`}},
64-
{name: `C`, args: []string{`bool`}},
74+
{name: `D`},
6575
},
66-
want: "struct{X int; Y bool}",
76+
want: `func()`,
77+
substWant: `{}`,
6778
},
6879
{
6980
nesting: []namedType{
7081
{name: `D`},
7182
{name: `E`, args: []string{`int`}},
7283
},
73-
want: "struct{X int}",
84+
want: `struct{X int}`,
85+
substWant: `{V->int}`,
7486
},
7587
{
7688
nesting: []namedType{
7789
{name: `F`, args: []string{`int`}},
7890
},
79-
want: `struct{X int}`,
91+
want: `struct{X int}`,
92+
substWant: `{W->int}`,
8093
},
8194
} {
8295
if len(test.nesting) == 0 {
83-
t.Fatal(`Must have at least one names type to instantiate`)
96+
t.Fatalf(`Test %d: Must have at least one names type to instantiate`, i)
8497
}
8598

8699
ctxt := types.NewContext()
@@ -90,7 +103,7 @@ func TestNestedSubstInGenericFunction(t *testing.T) {
90103
for _, nt := range test.nesting {
91104
obj = scope.Lookup(nt.name)
92105
if obj == nil {
93-
t.Fatalf(`Failed to find %s in package scope`, nt.name)
106+
t.Fatalf(`Test %d: Failed to find %s in package scope`, i, nt.name)
94107
}
95108
if fn, ok := obj.(*types.Func); ok {
96109
scope = fn.Scope()
@@ -100,25 +113,24 @@ func TestNestedSubstInGenericFunction(t *testing.T) {
100113
subst = New(ctxt, tp, args, subst)
101114
}
102115

103-
shouldNotPanic(t, func() {
116+
func() {
117+
defer func() {
118+
if r := recover(); r != nil {
119+
t.Errorf(`Test %d: panicked: %v`, i, r)
120+
}
121+
}()
122+
104123
stInst := subst.Type(obj.Type().Underlying())
105124
if got := stInst.String(); got != test.want {
106-
t.Errorf("%s.typ(%s) = %v, want %v", subst, obj.Type().Underlying(), got, test.want)
125+
t.Errorf("Test %d: %s.typ(%s): got %v, want %v", i, subst, obj.Type().Underlying(), got, test.want)
126+
}
127+
if got := subst.String(); got != test.substWant {
128+
t.Errorf("Test %d: subst string got %v, want %v", i, got, test.substWant)
107129
}
108-
})
130+
}()
109131
}
110132
}
111133

112-
func shouldNotPanic(t *testing.T, f func()) {
113-
t.Helper()
114-
defer func() {
115-
if r := recover(); r != nil {
116-
t.Errorf(`panicked: %v`, r)
117-
}
118-
}()
119-
f()
120-
}
121-
122134
func getTypeParams(t *testing.T, typ types.Type) *types.TypeParamList {
123135
switch typ := typ.(type) {
124136
case *types.Named:
@@ -140,7 +152,7 @@ func getTypeParams(t *testing.T, typ types.Type) *types.TypeParamList {
140152
func evalType(t *testing.T, fSet *token.FileSet, pkg *types.Package, expr string) types.Type {
141153
tv, err := types.Eval(fSet, pkg, 0, expr)
142154
if err != nil {
143-
t.Fatalf("Eval(%s) failed: %v", expr, err)
155+
t.Fatalf(`Eval(%s) failed: %v`, expr, err)
144156
}
145157
return tv.Type
146158
}

0 commit comments

Comments
 (0)