1
0
mirror of https://github.com/golang/go synced 2024-11-17 14:44:44 -07:00

[dev.typeparams] cmd/compile: tweaks to match types2

This CL makes a handful of changes to either bring existing compiler
output consistent with what types2 produces or to make it easier to
reproduce with types2:

1. The position for embedded fields is corrected to the position of
the syntax.Field, rather than the syntax.Type.

2. Methods and embedded types are sorted in export data the same way
that types2 sorts them.

3. Don't write out position information for OLITERALs that don't have
their own position (i.e., references to named constants).

Change-Id: Ic3979215ae9ef280cfbba7b44c236e03fc12a2ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/323209
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2021-05-26 19:52:31 -07:00
parent c2c1b53b39
commit de5d1aca5e
4 changed files with 38 additions and 13 deletions

View File

@ -986,6 +986,8 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
}
func (p *noder) embedded(typ syntax.Expr) *ir.Field {
pos := p.pos(syntax.StartPos(typ))
op, isStar := typ.(*syntax.Operation)
if isStar {
if op.Op != syntax.Mul || op.Y != nil {
@ -995,11 +997,11 @@ func (p *noder) embedded(typ syntax.Expr) *ir.Field {
}
sym := p.packname(typ)
n := ir.NewField(p.pos(typ), typecheck.Lookup(sym.Name), importName(sym).(ir.Ntype), nil)
n := ir.NewField(pos, typecheck.Lookup(sym.Name), importName(sym).(ir.Ntype), nil)
n.Embedded = true
if isStar {
n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
n.Ntype = ir.NewStarExpr(pos, n.Ntype)
}
return n
}

View File

@ -540,9 +540,12 @@ func (p *iexporter) doDecl(n *ir.Name) {
break
}
ms := t.Methods()
w.uint64(uint64(ms.Len()))
for _, m := range ms.Slice() {
// Sort methods, for consistency with types2.
methods := append([]*types.Field(nil), t.Methods().Slice()...)
sort.Sort(types.MethodsByName(methods))
w.uint64(uint64(len(methods)))
for _, m := range methods {
w.pos(m.Pos)
w.selector(m.Sym)
w.param(m.Type.Recv())
@ -550,7 +553,7 @@ func (p *iexporter) doDecl(n *ir.Name) {
}
w.typeExt(t)
for _, m := range ms.Slice() {
for _, m := range methods {
w.methExt(m)
}
@ -939,6 +942,12 @@ func (w *exportWriter) doTyp(t *types.Type) {
}
}
// Sort methods and embedded types, for consistency with types2.
// Note: embedded types may be anonymous, and types2 sorts them
// with sort.Stable too.
sort.Sort(types.MethodsByName(methods))
sort.Stable(types.EmbeddedsByName(embeddeds))
w.startType(interfaceType)
w.setPkg(t.Pkg(), true)
@ -1590,7 +1599,11 @@ func (w *exportWriter) expr(n ir.Node) {
case ir.OLITERAL:
w.op(ir.OLITERAL)
if ir.HasUniquePos(n) {
w.pos(n.Pos())
} else {
w.pos(src.NoXPos)
}
w.value(n.Type(), n.Val())
case ir.ONAME:

View File

@ -126,10 +126,15 @@ func expandiface(t *Type) {
// (including broken ones, if any) and add to t's
// method set.
for _, t1 := range m.Type.AllMethods().Slice() {
// Use m.Pos rather than t1.Pos to preserve embedding position.
f := NewField(m.Pos, t1.Sym, t1.Type)
addMethod(f, false)
// Clear position after typechecking, for consistency with types2.
f.Pos = src.NoXPos
}
// Clear position after typechecking, for consistency with types2.
m.Pos = src.NoXPos
}
sort.Sort(MethodsByName(methods))

View File

@ -4,11 +4,16 @@
package types
// MethodsByName sorts methods by symbol.
// MethodsByName sorts methods by name.
type MethodsByName []*Field
func (x MethodsByName) Len() int { return len(x) }
func (x MethodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x MethodsByName) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
// EmbeddedsByName sorts embedded types by name.
type EmbeddedsByName []*Field
func (x EmbeddedsByName) Len() int { return len(x) }
func (x EmbeddedsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x EmbeddedsByName) Less(i, j int) bool { return x[i].Type.Sym().Less(x[j].Type.Sym()) }