Description
Go version
go version go1.21.4 linux/amd64
What operating system and processor architecture are you using (go env
)?
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/jm/.cache/go-build'
GOENV='/home/jm/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/jm/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/jm/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/jm/src/jmattheis/goverter/test/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build961093412=/tmp/go-build -gno-record-gcc-switches'
What did you do?
I'm trying to do types.Type
assignable checks with types from different golang.org/x/tools/go/packages.Load
calls but they don't work as I'd expect. Here is an example to reproduce:
module jmattheis/issue
go 1.21.4
require golang.org/x/tools v0.16.0
require golang.org/x/mod v0.14.0 // indirect
package main
import (
"fmt"
"go/types"
"golang.org/x/tools/go/packages"
)
type Input struct{ ID string }
func main() {
one := load("./").Types.Scope().Lookup("Input").(*types.TypeName).Type()
two := load("./").Types.Scope().Lookup("Input").(*types.TypeName).Type()
fmt.Println("one =", one.String())
fmt.Println("two =", two.String())
fmt.Println("identical =", types.Identical(one, two))
}
func load(pkg string) *packages.Package {
cfg := &packages.Config{
Mode: packages.NeedSyntax | packages.NeedCompiledGoFiles | packages.NeedTypes |
packages.NeedModule | packages.NeedFiles | packages.NeedName | packages.NeedImports,
}
pkgs, err := packages.Load(cfg, pkg)
if err != nil { panic(err) }
if len(pkgs[0].Errors) != 0 { panic(pkgs[0].Errors) }
return pkgs[0]
}
My actual use-case is a little more complex with with parsing multiple different packages and then comparing types between them mainly with types.AssignableTo
which uses types.Identical
.
I could load all all my packages in one golang.org/x/tools/go/packages.Load
call, but this would make my application more complex and I think the current behavior of go/types.Identical
isn't obvious when using it.
What did you expect to see?
go/types.Identical
should return true
when supplying the same types. Even if the types are from different packages.Load
calls.
What did you see instead?
The string representation is the same but the types aren't identical.
one = jmattheis/issue.Input
two = jmattheis/issue.Input
identical = false
The call to indenticalOrigin(x, y)
inside predicates.go
returns false
.