1
0
mirror of https://github.com/golang/go synced 2024-11-23 19:30:05 -07:00

[dev.typeparams] cmd/compile/internal/types2: bring over subst.go changes from go/types

This CL make this code match closely with the go/types version
(see https://golang.org/cl/276253).

Change-Id: I2b7841309fdbda7e2c9533768bd98317729b13b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/276814
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2020-12-09 17:09:14 -08:00
parent ddf44904f1
commit a20021227e

View File

@ -1,4 +1,3 @@
// UNREVIEWED
// Copyright 2018 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.
@ -29,7 +28,7 @@ func makeSubstMap(tpars []*TypeName, targs []Type) *substMap {
assert(len(tpars) == len(targs))
proj := make(map[*TypeParam]Type, len(tpars))
for i, tpar := range tpars {
// We must expand type arguments otherwise *Instance
// We must expand type arguments otherwise *instance
// types end up as components in composite types.
// TODO(gri) explain why this causes problems, if it does
targ := expand(targs[i]) // possibly nil
@ -71,7 +70,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis
}()
}
assert(poslist == nil || len(poslist) <= len(targs))
assert(len(poslist) <= len(targs))
// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
var tparams []*TypeName
@ -81,9 +80,10 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis
case *Signature:
tparams = t.tparams
defer func() {
// If we had an unexpected failure somewhere don't
// panic below when asserting res.(*Signature).
if res == nil {
// If we had an unexpected failure somewhere don't panic below when
// asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
// is returned.
if _, ok := res.(*Signature); !ok {
return
}
// If the signature doesn't use its type parameters, subst
@ -153,6 +153,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis
if m, wrong := check.missingMethod(targ, iface, true); m != nil {
// TODO(gri) needs to print updated name to avoid major confusion in error message!
// (print warning for now)
// Old warning:
// check.softErrorf(pos, "%s does not satisfy %s (warning: name not updated) = %s (missing method %s)", targ, tpar.bound, iface, m)
if m.name == "==" {
// We don't want to report "missing method ==".
@ -175,7 +176,6 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis
if iface.allTypes == nil {
continue // nothing to do
}
// iface.allTypes != nil
// If targ is itself a type parameter, each of its possible types, but at least one, must be in the
// list of iface types (i.e., the targ type list must be a non-empty subset of the iface types).
@ -278,7 +278,9 @@ func (subst *subster) typ(typ Type) Type {
results := subst.tuple(t.results)
if recv != t.recv || params != t.params || results != t.results {
return &Signature{
rparams: t.rparams,
rparams: t.rparams,
// TODO(gri) Why can't we nil out tparams here, rather than in
// instantiate above?
tparams: t.tparams,
scope: t.scope,
recv: recv,
@ -343,7 +345,6 @@ func (subst *subster) typ(typ Type) Type {
var new_targs []Type
if len(t.targs) > 0 {
// already instantiated
dump(">>> %s already instantiated", t)
assert(len(t.targs) == len(t.tparams))
@ -367,13 +368,10 @@ func (subst *subster) typ(typ Type) Type {
dump(">>> nothing to substitute in %s", t)
return t // nothing to substitute
}
} else {
// not yet instantiated
dump(">>> first instantiation of %s", t)
new_targs = subst.smap.targs
}
// before creating a new named type, check if we have this one already
@ -419,9 +417,9 @@ func (subst *subster) typ(typ Type) Type {
func instantiatedHash(typ *Named, targs []Type) string {
var buf bytes.Buffer
writeTypeName(&buf, typ.obj, nil)
buf.WriteByte('(')
buf.WriteByte('[')
writeTypeList(&buf, targs, nil, nil)
buf.WriteByte(')')
buf.WriteByte(']')
// With respect to the represented type, whether a
// type is fully expanded or stored as instance