1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package b
6
7import "./a"
8
9type T struct{ a.T }
10
11func (T) m() { println("ok") }
12
13// The compiler used to not pay attention to package for non-exported
14// methods when statically constructing itabs. The consequence of this
15// was that the call to b.F1(b.T{}) in c.go would create an itab using
16// a.T.m instead of b.T.m.
17func F1(i interface{ m() }) { i.m() }
18
19// The interface method calling convention depends on interface method
20// sets being sorted in the same order across compilation units.  In
21// the test case below, at the call to b.F2(b.T{}) in c.go, the
22// interface method set is sorted as { a.m(); b.m() }.
23//
24// However, while compiling package b, its package path is set to "",
25// so the code produced for F2 uses { b.m(); a.m() } as the method set
26// order. So again, it ends up calling the wrong method.
27//
28// Also, this function is marked noinline because it's critical to the
29// test that the interface method call happen in this compilation
30// unit, and the itab construction happens in c.go.
31//
32//go:noinline
33func F2(i interface {
34	m()
35	a.I // embeds m() from package a
36}) {
37	i.m()
38}
39