go/ast/astutil: fix panic when rewriting multi-argument type instances

Use the typeparams helper package to fix AST rewriting in go/ast/astutil
when encountering the new ListExpr type.

This is liable to break in the future when the go/ast API changes, but
at least it will be easy to find by virtue of using internal/typeparams.

Fixes golang/vscode-go#1551

Change-Id: Id34bbcdede9024ed9818bef6d73a19e993dd76a8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/326131
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/go/ast/astutil/rewrite.go b/go/ast/astutil/rewrite.go
index cf72ea9..b949fc8 100644
--- a/go/ast/astutil/rewrite.go
+++ b/go/ast/astutil/rewrite.go
@@ -9,6 +9,8 @@
 	"go/ast"
 	"reflect"
 	"sort"
+
+	"golang.org/x/tools/internal/typeparams"
 )
 
 // An ApplyFunc is invoked by Apply for each node n, even if n is nil,
@@ -437,7 +439,11 @@
 		}
 
 	default:
-		panic(fmt.Sprintf("Apply: unexpected node type %T", n))
+		if typeparams.IsListExpr(n) {
+			a.applyList(n, "ElemList")
+		} else {
+			panic(fmt.Sprintf("Apply: unexpected node type %T", n))
+		}
 	}
 
 	if a.post != nil && !a.post(&a.cursor) {
diff --git a/go/ast/astutil/rewrite_test.go b/go/ast/astutil/rewrite_test.go
index 1c86970..3a74afa 100644
--- a/go/ast/astutil/rewrite_test.go
+++ b/go/ast/astutil/rewrite_test.go
@@ -13,13 +13,16 @@
 	"testing"
 
 	"golang.org/x/tools/go/ast/astutil"
+	"golang.org/x/tools/internal/typeparams"
 )
 
-var rewriteTests = [...]struct {
+type rewriteTest struct {
 	name       string
 	orig, want string
 	pre, post  astutil.ApplyFunc
-}{
+}
+
+var rewriteTests = []rewriteTest{
 	{name: "nop", orig: "package p\n", want: "package p\n"},
 
 	{name: "replace",
@@ -190,6 +193,34 @@
 	},
 }
 
+func init() {
+	if typeparams.Enabled {
+		rewriteTests = append(rewriteTests, rewriteTest{
+			name: "replace",
+			orig: `package p
+
+type T[P1, P2 any] int
+
+type R T[int, string]
+`,
+			want: `package p
+
+type T[P1, P2 any] int32
+
+type R T[int32, string]
+`,
+			post: func(c *astutil.Cursor) bool {
+				if ident, ok := c.Node().(*ast.Ident); ok {
+					if ident.Name == "int" {
+						c.Replace(ast.NewIdent("int32"))
+					}
+				}
+				return true
+			},
+		})
+	}
+}
+
 func valspec(name, typ string) *ast.ValueSpec {
 	return &ast.ValueSpec{Names: []*ast.Ident{ast.NewIdent(name)},
 		Type: ast.NewIdent(typ),
diff --git a/internal/typeparams/typeparams.go b/internal/typeparams/typeparams.go
index 624ce37..6b7958a 100644
--- a/internal/typeparams/typeparams.go
+++ b/internal/typeparams/typeparams.go
@@ -101,5 +101,5 @@
 		return nil, nil
 	}
 	inf := info.Inferred[e]
-	return inf.Targs, inf.Sig
+	return inf.TArgs, inf.Sig
 }