diff --git a/src/go/types/subst.go b/src/go/types/subst.go index 546d18c9a9..e183d7a79a 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -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() } diff --git a/src/go/types/testdata/contracts.go2 b/src/go/types/testdata/contracts.go2 index 6ea2a45040..37d62010d4 100644 --- a/src/go/types/testdata/contracts.go2 +++ b/src/go/types/testdata/contracts.go2 @@ -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 \ No newline at end of file diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go index 4b27045282..f9d261b115 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -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 := "" if obj != nil {