From 45eb8a74f0c243d4289a5908a02a5596ad391fc7 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 27 Nov 2019 16:06:14 -0800 Subject: [PATCH] go/types: added another example to examples/types.go2 Also: disabled aggressive rewriting of methods upon type instantiation (Need to first figure out what we really need to do.) Change-Id: I6fba78d60963534ebfe130164058ac1fbed7e5a3 --- src/go/types/examples/types.go2 | 18 ++++++++++++++++++ src/go/types/subst.go | 20 +++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/go/types/examples/types.go2 b/src/go/types/examples/types.go2 index b07477549f..8df0a0415c 100644 --- a/src/go/types/examples/types.go2 +++ b/src/go/types/examples/types.go2 @@ -81,3 +81,21 @@ func _() { x1a = x2a // ERROR assignment x1a.f = x2a.f } + +// Another interesting corner case is parameterized types that don't use +// their type arguments. For instance: +type T(type P) struct{} + +var xint T(int) +var xbool T(bool) + +// Are these two variables of the same type? After all, their underlying +// types are identical. We consider them to be different because each type +// instantiation creates a new named type, in this case T and T +// even if their underlying types are identical. This is sensible because +// we might still have methods that have different signatures or behave +// differently depending on the type arguments, and thus we can't possibly +// consider such types identical. Consequently: +func _() { + xint = xbool // ERROR assignment +} \ No newline at end of file diff --git a/src/go/types/subst.go b/src/go/types/subst.go index c36f518b0b..9ea48ea657 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -194,16 +194,18 @@ func (subst *subster) typ(typ Type) Type { 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) - } + // 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? return named