diff --git a/src/go/types/subst.go b/src/go/types/subst.go index b8e732d04b..50ac670462 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -122,22 +122,25 @@ func (s *subster) typ(typ Type) (res Type) { } case *Named: + // if not all type parameters are known, create a parameterized type + if isParameterizedList(s.targs) { + return &Parameterized{t.obj, s.targs} + } + // TODO(gri) revisit name creation (function local types, etc.) and factor out name := TypeString(t, nil) + "<" + typeListString(s.targs) + ">" - //s.check.dump("- %s => %s", t, name) if tname, found := s.check.typMap[name]; found { - //s.check.dump("- found %s", tname) return tname.typ } + // create a new named type and populate caches to avoid endless recursion // TODO(gri) should use actual instantiation position tname := NewTypeName(t.obj.pos, s.check.pkg, name, nil) s.check.typMap[name] = tname named := NewNamed(tname, nil, nil) s.cache[t] = named - //s.check.dump("- installed %s", tname) named.underlying = s.typ(t.underlying).Underlying() - //s.check.dump("- finished %s", tname) + // instantiate custom methods as necessary for _, m := range t.methods { // methods may not have a fully set up signature yet diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 index 8472f85c44..ef76018d36 100644 --- a/src/go/types/testdata/tmp.go2 +++ b/src/go/types/testdata/tmp.go2 @@ -1,13 +1,30 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - package p -type S(type T) struct { - f T +type Pair(type K) struct { + key K } -func (r S(T)) m() T { - return r.f -} \ No newline at end of file +type Receiver(type T) struct { + values T +} + +type Iterator(type K) struct { + r Receiver(Pair(K)) +} + +func (r Receiver(T)) Values() T { + return r.values +} + +func Values (type T) (r Receiver(T)) T { + return r.values +} + +func (it Iterator(K)) Next() K { + // x := it.r.Values() + x := Values(Pair(K))(it.r) + // it : Iterator(K) + // it.r : Receiver(Pair(K)) + // it.r.Values: Pair(K) + return x.key +} diff --git a/src/go/types/testdata/typeinst2.go2 b/src/go/types/testdata/typeinst2.go2 index 80a18d0495..367ee23d25 100644 --- a/src/go/types/testdata/typeinst2.go2 +++ b/src/go/types/testdata/typeinst2.go2 @@ -56,3 +56,25 @@ func (l List(E)) Head() (_ E, _ bool) { } return } + +// A test case for instantiating types with other types (extracted from map.go2) + +type Pair(type K) struct { + key K +} + +type Receiver(type T) struct { + values T +} + +type Iterator(type K) struct { + r Receiver(Pair(K)) +} + +func Values (type T) (r Receiver(T)) T { + return r.values +} + +func (it Iterator(K)) Next() K { + return Values(Pair(K))(it.r).key +}