diff options
author | Tim King <taking@google.com> | 2022-05-11 14:12:33 -0700 |
---|---|---|
committer | Tim King <taking@google.com> | 2022-05-16 16:39:03 +0000 |
commit | 1e55371df567127a49b447aa65b92cb04ad99138 (patch) | |
tree | 97b41ae80e9ca145bc77566669d2c9aaec0b433d /go/ssa/builder_test.go | |
parent | 29d48d6d9d17e86ff120ff4ac25270233728b12b (diff) | |
download | golang-x-tools-1e55371df567127a49b447aa65b92cb04ad99138.tar.gz |
go/ssa: fix *SelectorExpr within *IndexExpr handling
When a *IndexExpr or *IndexListExpr expr is over a *SelectorExpr and
expr denotes an instantiation, build expr as the *SelectorExpr.
Fixes golang/go#52834
Change-Id: I9a69ac28a6e8fb0ee9eb45db8675872b75d69a0f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/405555
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Tim King <taking@google.com>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'go/ssa/builder_test.go')
-rw-r--r-- | go/ssa/builder_test.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/go/ssa/builder_test.go b/go/ssa/builder_test.go index 6b9c79803..ba9aaf768 100644 --- a/go/ssa/builder_test.go +++ b/go/ssa/builder_test.go @@ -20,6 +20,7 @@ import ( "strings" "testing" + "golang.org/x/tools/go/buildutil" "golang.org/x/tools/go/loader" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa/ssautil" @@ -823,3 +824,56 @@ func sliceMax(s []int) []int { return s[a():b():c()] } }) } } + +// TestGenericFunctionSelector ensures generic functions from other packages can be selected. +func TestGenericFunctionSelector(t *testing.T) { + if !typeparams.Enabled { + t.Skip("TestGenericFunctionSelector uses type parameters.") + } + + pkgs := map[string]map[string]string{ + "main": {"m.go": `package main; import "a"; func main() { a.F[int](); a.G[int,string](); a.H(0) }`}, + "a": {"a.go": `package a; func F[T any](){}; func G[S, T any](){}; func H[T any](a T){} `}, + } + + for _, mode := range []ssa.BuilderMode{ + ssa.SanityCheckFunctions, + ssa.SanityCheckFunctions | ssa.InstantiateGenerics, + } { + conf := loader.Config{ + Build: buildutil.FakeContext(pkgs), + } + conf.Import("main") + + lprog, err := conf.Load() + if err != nil { + t.Errorf("Load failed: %s", err) + } + if lprog == nil { + t.Fatalf("Load returned nil *Program") + } + // Create and build SSA + prog := ssautil.CreateProgram(lprog, mode) + p := prog.Package(lprog.Package("main").Pkg) + p.Build() + + var callees []string // callees of the CallInstruction.String() in main(). + for _, b := range p.Func("main").Blocks { + for _, i := range b.Instrs { + if call, ok := i.(ssa.CallInstruction); ok { + if callee := call.Common().StaticCallee(); call != nil { + callees = append(callees, callee.String()) + } else { + t.Errorf("CallInstruction without StaticCallee() %q", call) + } + } + } + } + sort.Strings(callees) // ignore the order in the code. + + want := "[a.F[[int]] a.G[[int string]] a.H[[int]]]" + if got := fmt.Sprint(callees); got != want { + t.Errorf("Expected main() to contain calls %v. got %v", want, got) + } + } +} |