mirror of https://github.com/golang/go.git
go/types: factored writeTypeList, various minor cleanups, added test case
Change-Id: I971633c93099ab69466dc152e23aa9cf3ded50e0
This commit is contained in:
parent
5504084423
commit
6e1fbb8a53
|
|
@ -124,7 +124,7 @@ func includesType(typ Type, iface *Interface) bool {
|
|||
// subst returns the type typ with its type parameters tparams replaced by
|
||||
// the corresponding type arguments targs, recursively.
|
||||
func (check *Checker) subst(pos token.Pos, typ Type, tpars []*TypeName, targs []Type) Type {
|
||||
//assert(len(tpars) == len(targs)) // bounds may have only some type parameters
|
||||
assert(len(tpars) == len(targs)) // bounds may have only some type parameters
|
||||
if len(tpars) == 0 {
|
||||
return typ
|
||||
}
|
||||
|
|
@ -281,24 +281,10 @@ func (subst *subster) typ(typ Type) Type {
|
|||
subst.cache[t] = named
|
||||
dump(">>> subst %s(%s) with %s (new: %s)", t.underlying, subst.tpars, subst.targs, new_targs)
|
||||
named.underlying = subst.typ(t.underlying)
|
||||
|
||||
named.methods = t.methods // for now
|
||||
// TODO(gri) how much work do we really need to do here?
|
||||
// instantiate custom methods as necessary
|
||||
// for _, m := range t.methods {
|
||||
// // methods may not have a fully set up signature yet
|
||||
// dump(">>> instantiate %s", m)
|
||||
// subst.check.objDecl(m, nil)
|
||||
// sig := subst.check.subst(m.pos, m.typ, subst.tpars /*m.tparams*/, subst.targs).(*Signature)
|
||||
// m1 := NewFunc(m.pos, m.pkg, m.name, sig)
|
||||
// dump(">>> %s: method %s => %s", name, m, m1)
|
||||
// named.methods = append(named.methods, m1)
|
||||
// }
|
||||
// TODO(gri) update the method receivers?
|
||||
named.methods = t.methods // methods will be customized when used
|
||||
return named
|
||||
|
||||
case *TypeParam:
|
||||
assert(len(subst.tpars) == len(subst.targs)) // TODO(gri) don't need this?
|
||||
// TODO(gri) Can we do this with direct indexing somehow? Or use a map instead?
|
||||
for i, tpar := range subst.tpars {
|
||||
if tpar.typ == t {
|
||||
|
|
@ -406,13 +392,8 @@ func (subst *subster) typeList(in []Type) (out []Type, copied bool) {
|
|||
return
|
||||
}
|
||||
|
||||
func typeListString(targs []Type) string {
|
||||
func typeListString(list []Type) string {
|
||||
var buf bytes.Buffer
|
||||
for i, arg := range targs {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
WriteType(&buf, arg, nil)
|
||||
}
|
||||
writeTypeList(&buf, list, nil, nil)
|
||||
return buf.String()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,3 +209,14 @@ contract B2(T) {
|
|||
type T4(type P B2) P
|
||||
|
||||
func _(type P B2)(x T4(P))
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Type parameters may be from different parameterized objects
|
||||
|
||||
func f2(type P)(x P) P {
|
||||
type T(type Q) struct { x P; y Q }
|
||||
v := T(int){x, 42}
|
||||
return v.x
|
||||
}
|
||||
|
||||
// TODO(gri) more complex examples such as this
|
||||
|
|
@ -203,12 +203,7 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
|
|||
}
|
||||
if len(t.types) > 0 {
|
||||
buf.WriteString("type ")
|
||||
for i, typ := range t.types {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
writeType(buf, typ, qf, visited)
|
||||
}
|
||||
writeTypeList(buf, t.types, qf, visited)
|
||||
empty = false
|
||||
}
|
||||
if !empty && len(t.embeddeds) > 0 {
|
||||
|
|
@ -311,6 +306,15 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
|
|||
}
|
||||
}
|
||||
|
||||
func writeTypeList(buf *bytes.Buffer, list []Type, qf Qualifier, visited []Type) {
|
||||
for i, typ := range list {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
writeType(buf, typ, qf, visited)
|
||||
}
|
||||
}
|
||||
|
||||
func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
|
||||
s := "<Named w/o object>"
|
||||
if obj != nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue