]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: sort iface fields before expansion
authorMatthew Dempsky <mdempsky@google.com>
Wed, 2 Jun 2021 01:45:40 +0000 (18:45 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 2 Jun 2021 21:34:56 +0000 (21:34 +0000)
For toolstash -cmp compatibility with types2, we also need to sort
fields (or at least the embedded types) *before* expanding them. This
is relevant to what position information and parameter names are used
for methods when embedded interfaces have overlapping methods.

This came up in archive/zip, which has:

type fileInfoDirEntry interface {
fs.FileInfo
fs.DirEntry
}

and both of these embedded interfaces in turn have an "IsDir() bool"
method. Traditionally, cmd/compile would keep the method from
fs.FileInfo.IsDir, but with types2 it will now keep fs.DirEntry.IsDir
instead. This doesn't affect correctness at all, but it does end up in
DWARF sometimes.

Change-Id: Iac8d6321894be335466a76b5bf8a0c1b15a3581b
Reviewed-on: https://go-review.googlesource.com/c/go/+/324330
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/types/size.go

index e6ca4556b94765d639110509ae762366b78883f3..f5a74f83b396c65ace632e4a259558d3250a2c37 100644 (file)
@@ -90,6 +90,26 @@ func expandiface(t *Type) {
                methods = append(methods, m)
        }
 
+       {
+               methods := t.Methods().Slice()
+               sort.SliceStable(methods, func(i, j int) bool {
+                       mi, mj := methods[i], methods[j]
+
+                       // Sort embedded types by type name (if any).
+                       if mi.Sym == nil && mj.Sym == nil {
+                               return mi.Type.Sym().Less(mj.Type.Sym())
+                       }
+
+                       // Sort methods before embedded types.
+                       if mi.Sym == nil || mj.Sym == nil {
+                               return mi.Sym != nil
+                       }
+
+                       // Sort methods by symbol name.
+                       return mi.Sym.Less(mj.Sym)
+               })
+       }
+
        for _, m := range t.Methods().Slice() {
                if m.Sym == nil {
                        continue