From 498a48327fae3b57e2696322f1ce2b681ccca668 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 1 Jun 2021 18:45:40 -0700 Subject: [PATCH] [dev.typeparams] cmd/compile: sort iface fields before expansion 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 Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types/size.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go index e6ca4556b94..f5a74f83b39 100644 --- a/src/cmd/compile/internal/types/size.go +++ b/src/cmd/compile/internal/types/size.go @@ -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