[dev.typeparams] cmd/compile: fix handling of Nname field in (*subster).tstruct.

We want to keep the Nname references for external function references in
tstruct (not remove them, as is currently happening). We only change the
Nname reference (translate it) when it appears in subst.vars[].

New export/import test sliceimp.go which includes some of these external
function references.

Change-Id: Ie3d73bd989a16082f0cebfb566e0a7faeda55e60
Reviewed-on: https://go-review.googlesource.com/c/go/+/321735
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
This commit is contained in:
Dan Scales 2021-05-11 14:14:30 -07:00
parent 8d2b4cb6cc
commit 5b1120fac7
4 changed files with 343 additions and 10 deletions

View file

@ -565,10 +565,10 @@ func (subst *subster) list(l []ir.Node) []ir.Node {
}
// tstruct substitutes type params in types of the fields of a structure type. For
// each field, if Nname is set, tstruct also translates the Nname using
// subst.vars, if Nname is in subst.vars. To always force the creation of a new
// (top-level) struct, regardless of whether anything changed with the types or
// names of the struct's fields, set force to true.
// each field, tstruct copies the Nname, and translates it if Nname is in
// subst.vars. To always force the creation of a new (top-level) struct,
// regardless of whether anything changed with the types or names of the struct's
// fields, set force to true.
func (subst *subster) tstruct(t *types.Type, force bool) *types.Type {
if t.NumFields() == 0 {
if t.HasTParam() {
@ -597,15 +597,21 @@ func (subst *subster) tstruct(t *types.Type, force bool) *types.Type {
// the type param, not the instantiated type).
newfields[i] = types.NewField(f.Pos, f.Sym, t2)
if f.Nname != nil {
// f.Nname may not be in subst.vars[] if this is
// a function name or a function instantiation type
// that we are translating
v := subst.vars[f.Nname.(*ir.Name)]
// Be careful not to put a nil var into Nname,
// since Nname is an interface, so it would be a
// non-nil interface.
if v != nil {
// This is the case where we are
// translating the type of the function we
// are substituting, so its dcls are in
// the subst.vars table, and we want to
// change to reference the new dcl.
newfields[i].Nname = v
} else {
// This is the case where we are
// translating the type of a function
// reference inside the function we are
// substituting, so we leave the Nname
// value as is.
newfields[i].Nname = f.Nname
}
}
}