]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use t.AllMethods when sorting typesByString
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sun, 30 May 2021 08:35:06 +0000 (15:35 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 8 Jun 2021 12:17:50 +0000 (12:17 +0000)
For interface types, t.Methods contains only unexpanded method set, i.e
exclusive of interface embedding. Thus, we can't use it to detect an
interface contains embedding empty interface, like in:

type EI interface{}

func f() interface{ EI } {
return nil
}

At the time we generate runtime types, we want to check against the full
method set of interface instead.

Fixes #46386

Change-Id: Idff53ad39276be6632eb5932b76e855c15cbdd2e
Reviewed-on: https://go-review.googlesource.com/c/go/+/323649
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/reflectdata/reflect.go
test/fixedbugs/issue46386.go [new file with mode: 0644]

index b3688fca673b29ab9436529ed14c4f50398c1c2e..e07294be0f92bb686a04b194f43bff015de5a201 100644 (file)
@@ -1475,8 +1475,8 @@ func (a typesByString) Less(i, j int) bool {
        // will be equal for the above checks, but different in DWARF output.
        // Sort by source position to ensure deterministic order.
        // See issues 27013 and 30202.
-       if a[i].t.Kind() == types.TINTER && a[i].t.Methods().Len() > 0 {
-               return a[i].t.Methods().Index(0).Pos.Before(a[j].t.Methods().Index(0).Pos)
+       if a[i].t.Kind() == types.TINTER && a[i].t.AllMethods().Len() > 0 {
+               return a[i].t.AllMethods().Index(0).Pos.Before(a[j].t.AllMethods().Index(0).Pos)
        }
        return false
 }
diff --git a/test/fixedbugs/issue46386.go b/test/fixedbugs/issue46386.go
new file mode 100644 (file)
index 0000000..89dea8a
--- /dev/null
@@ -0,0 +1,32 @@
+// compile -p=main
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type I interface {
+       M() interface{}
+}
+
+type S1 struct{}
+
+func (S1) M() interface{} {
+       return nil
+}
+
+type EI interface{}
+
+type S struct{}
+
+func (S) M(as interface{ I }) {}
+
+func f() interface{ EI } {
+       return &S1{}
+}
+
+func main() {
+       var i interface{ I }
+       (&S{}).M(i)
+}