mirror of https://github.com/golang/go.git
go/types: fix a bug with type instantiation
Change-Id: I977bb5525a40d0e17c27bbc01d7c77426e1bad00
This commit is contained in:
parent
e73de77f33
commit
1f06612063
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue