Repository: go
Issue: go/types: improve documentation on `*types.Named` identity
Labels: Documentation,help wanted,NeedsFix

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.19beta1 linux/amd64
</pre>

### Does this issue reproduce with the latest release?

It also reproduces in Go 1.18.3.


### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ayke/.cache/go-build"
GOENV="/home/ayke/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ayke/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ayke:/home/ayke"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/ayke/src/github.com/tinygo-org/tinygo/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build898003955=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?

I am using golang.org/x/tools/go/ssa to build the SSA form for TinyGo.
We recently added generics support, which was surprisingly easy because the ssa package does all the hard work of instantiating generic functions.
Unfortunately, it resulted in an issue. Previously, we could rely on `*types.Named` to have pointer identity, meaning, that we could create a `map[*types.Named]someOtherType` and rely on the fact that every unique named type would have only one entry in the map.



### What did you expect to see?

I expected this to remain the same while adding support for generics.

### What did you see instead?

It broke. It works most of the time, but in some cases (in particular, methods on generic structs) there can be two `*types.Named` objects for the same named type.

Here is a reproducer:
https://go.dev/play/p/AIZZDnqqm0l?v=gotip

I've tried to look at the documentation and comments inside the package what the intended behavior is, but I see somewhat conflicting information. In any case, it would be very helpful if `*types.Named` would be unique again.

 1. This comment seems to suggest `*types.Named` is intended to have pointer identity but doesn't at the moment.
    https://github.com/golang/go/blob/2aa473cc54128c1498f80263763a2a876308e565/src/go/types/predicates.go#L428-L431
 2. [`types.Instantiate`](https://pkg.go.dev/go/types#Instantiate) says that not all types may be uniqued:
    > If ctxt is non-nil, it may be used to de-duplicate the instance against previous instances with the same identity. As a special case, generic *Signature origin types are only considered identical if they are pointer equivalent, so that instantiating distinct (but possibly identical) signatures will yield different instances. The use of a shared context does not guarantee that identical instances are deduplicated in all cases.
 3. The comment at the top of src/go/types/named.go says that `*types.Named` may not be unique:
    https://github.com/golang/go/blob/2aa473cc54128c1498f80263763a2a876308e565/src/go/types/named.go#L74-L81

From this, it appears to be a design decision to change the uniqueness of `*types.Named` pointers for generic types.
This is a problem for me, as I need a way to create unique IDs per `*types.Named` instance (`types.Identical` is not a solution, because you can't use it in a map). I tried `typ.Obj().Pkg().Path() + "." + typ.Obj().Name()` but that doesn't work for named types inside functions (which create a new scope but may have the same name as a named type in the outer scope).

I'm reporting this as a bug as it feels like a regression to me, even though it's not _technically_ a regression.