internal/pkgdoc: fix rendering of generics like atomic.Pointer

Fixes golang/go#54200.

Change-Id: I407b7368c524746b0f14c6ec5495c509794e331a
Reviewed-on: https://go-review.googlesource.com/c/website/+/420794
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/cmd/golangorg/server_test.go b/cmd/golangorg/server_test.go
index eae855a..d643c24 100644
--- a/cmd/golangorg/server_test.go
+++ b/cmd/golangorg/server_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"go/build"
 	"net/http/httptest"
 	"os"
 	"path/filepath"
@@ -24,10 +25,25 @@
 		t.Fatal(err)
 	}
 	for _, file := range files {
-		if filepath.ToSlash(file) != "testdata/live.txt" {
-			webtest.TestHandler(t, file, h)
+		switch filepath.ToSlash(file) {
+		case "testdata/live.txt":
+			continue
+		case "testdata/go1.19.txt":
+			if !haveRelease("go1.19") {
+				continue
+			}
+		}
+		webtest.TestHandler(t, file, h)
+	}
+}
+
+func haveRelease(release string) bool {
+	for _, tag := range build.Default.ReleaseTags {
+		if tag == release {
+			return true
 		}
 	}
+	return false
 }
 
 var bad = []string{
diff --git a/cmd/golangorg/testdata/go1.19.txt b/cmd/golangorg/testdata/go1.19.txt
new file mode 100644
index 0000000..e1c5fb7
--- /dev/null
+++ b/cmd/golangorg/testdata/go1.19.txt
@@ -0,0 +1,5 @@
+GET https://golang.org/pkg/sync/atomic/?m=old
+redirect == https://go.dev/pkg/sync/atomic/?m=old
+
+GET https://go.dev/pkg/sync/atomic/?m=old
+body contains func (x *Pointer[T]) Load() *T
diff --git a/internal/pkgdoc/doc.go b/internal/pkgdoc/doc.go
index 9058ffe..4481fd6 100644
--- a/internal/pkgdoc/doc.go
+++ b/internal/pkgdoc/doc.go
@@ -11,9 +11,6 @@
 
 import (
 	"bytes"
-	"golang.org/x/website/internal/backport/go/ast"
-	"golang.org/x/website/internal/backport/go/doc"
-	"golang.org/x/website/internal/backport/go/token"
 	"io"
 	"io/fs"
 	"io/ioutil"
@@ -29,7 +26,10 @@
 	"unicode/utf8"
 
 	"golang.org/x/website/internal/api"
+	"golang.org/x/website/internal/backport/go/ast"
 	"golang.org/x/website/internal/backport/go/build"
+	"golang.org/x/website/internal/backport/go/doc"
+	"golang.org/x/website/internal/backport/go/token"
 	"golang.org/x/website/internal/web"
 )
 
@@ -363,14 +363,14 @@
 	case *ast.FuncDecl:
 		name := d.Name.Name
 		if d.Recv != nil {
-			var typeName string
-			switch r := d.Recv.List[0].Type.(type) {
-			case *ast.StarExpr:
-				typeName = r.X.(*ast.Ident).Name
-			case *ast.Ident:
-				typeName = r.Name
+			r := d.Recv.List[0].Type
+			if star, ok := r.(*ast.StarExpr); ok { // *Name
+				r = star.X
 			}
-			name = typeName + "_" + name
+			if index, ok := r.(*ast.IndexExpr); ok { // Name[T]
+				r = index.X
+			}
+			name = r.(*ast.Ident).Name + "_" + name
 		}
 		names[name] = true
 	case *ast.GenDecl: