Help us shape the future of Go! Take the 2026 Go Developer Survey

Source file src/cmd/compile/internal/types2/methodorder_test.go

     1  // Copyright 2026 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  
     5  package types2_test
     6  
     7  import (
     8  	"internal/testenv"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  
    14  	"cmd/compile/internal/testimporter"
    15  	. "cmd/compile/internal/types2"
    16  )
    17  
    18  // TestImportedMethodOrder checks that methods of types imported from
    19  // export data appear in source order, as required by objectpath
    20  // (go.dev/issue/81188).
    21  func TestImportedMethodOrder(t *testing.T) {
    22  	testenv.MustHaveGoBuild(t)
    23  
    24  	const src = `package methodorder
    25  
    26  // T mixes generic and non-generic methods.
    27  type T struct{}
    28  
    29  func (T) A()               {}
    30  func (T) B[X any]()        {}
    31  func (T) C()               {}
    32  func (T) D[X, Y any](X, Y) {}
    33  func (T) E()               {}
    34  
    35  // U's underlying type refers to V, whose method body calls a generic
    36  // method of U, so encoding U's underlying type encodes U.G before the
    37  // rest of U.
    38  type U struct{ v *V }
    39  
    40  type V struct{}
    41  
    42  func (v *V) M(u *U) int { return u.G[int]() }
    43  
    44  func (*U) A()            {}
    45  func (*U) B()            {}
    46  func (*U) G[X any]() int { return 0 }
    47  func (*U) Z()            {}
    48  `
    49  	dir := t.TempDir()
    50  	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module methodorder\n\ngo 1.27\n"), 0666); err != nil {
    51  		t.Fatal(err)
    52  	}
    53  	if err := os.WriteFile(filepath.Join(dir, "methodorder.go"), []byte(src), 0666); err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	t.Chdir(dir) // so that the importer's go build uses dir's module
    57  
    58  	pkg, err := testimporter.NewImporter().ImportFrom(".", dir, 0)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	for _, test := range []struct {
    63  		typ  string
    64  		want string
    65  	}{
    66  		{"T", "A B C D E"},
    67  		{"U", "A B G Z"},
    68  	} {
    69  		named := pkg.Scope().Lookup(test.typ).Type().(*Named)
    70  		var names []string
    71  		for i := range named.NumMethods() {
    72  			names = append(names, named.Method(i).Name())
    73  		}
    74  		if got := strings.Join(names, " "); got != test.want {
    75  			t.Errorf("methods of %s = %s; want %s", test.typ, got, test.want)
    76  		}
    77  	}
    78  }
    79  

View as plain text