[dev.typeparams] cmd/compile: point StructKeyExpr at the types.Field

When constructing struct literals, importers need a way to specify
precisely which field to initialize without worrying about visibility
or those fields being blank. (A blank field doesn't actually need to
be initialized, but the expression needs to be evaluated still, and
with the right order-of-operations.)

This CL changes StructKeyExpr's Field field to point directly to the
corresponding types.Field, rather than merely holding a copy of its
Sym and Offset. This is akin to past changes to add
SelectorExpr.Selection.

Change-Id: I95b72b1788f73206fcebc22b456cf6b1186db6a7
Reviewed-on: https://go-review.googlesource.com/c/go/+/325031
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2021-06-04 00:01:22 -07:00
parent bad388744b
commit a94e4f5a85
9 changed files with 107 additions and 112 deletions

View file

@ -937,9 +937,7 @@ func transformCompLit(n *ir.CompLitExpr) (res ir.Node) {
f := t.Field(i)
n1 = assignconvfn(n1, f.Type)
sk := ir.NewStructKeyExpr(base.Pos, f.Sym, n1)
sk.Offset = f.Offset
ls[i] = sk
ls[i] = ir.NewStructKeyExpr(base.Pos, f, n1)
}
assert(len(ls) >= t.NumFields())
} else {
@ -948,33 +946,26 @@ func transformCompLit(n *ir.CompLitExpr) (res ir.Node) {
for i, l := range ls {
ir.SetPos(l)
if l.Op() == ir.OKEY {
kv := l.(*ir.KeyExpr)
key := kv.Key
kv := l.(*ir.KeyExpr)
key := kv.Key
// Sym might have resolved to name in other top-level
// package, because of import dot. Redirect to correct sym
// before we do the lookup.
s := key.Sym()
if id, ok := key.(*ir.Ident); ok && typecheck.DotImportRefs[id] != nil {
s = typecheck.Lookup(s.Name)
}
// An OXDOT uses the Sym field to hold
// the field to the right of the dot,
// so s will be non-nil, but an OXDOT
// is never a valid struct literal key.
assert(!(s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank()))
l = ir.NewStructKeyExpr(l.Pos(), s, kv.Value)
ls[i] = l
// Sym might have resolved to name in other top-level
// package, because of import dot. Redirect to correct sym
// before we do the lookup.
s := key.Sym()
if id, ok := key.(*ir.Ident); ok && typecheck.DotImportRefs[id] != nil {
s = typecheck.Lookup(s.Name)
}
assert(l.Op() == ir.OSTRUCTKEY)
l := l.(*ir.StructKeyExpr)
// An OXDOT uses the Sym field to hold
// the field to the right of the dot,
// so s will be non-nil, but an OXDOT
// is never a valid struct literal key.
assert(!(s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank()))
f := typecheck.Lookdot1(nil, l.Field, t, t.Fields(), 0)
l.Offset = f.Offset
f := typecheck.Lookdot1(nil, s, t, t.Fields(), 0)
l := ir.NewStructKeyExpr(l.Pos(), f, kv.Value)
ls[i] = l
l.Value = assignconvfn(l.Value, f.Type)
}