Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types: types.Identical is false for identical types loaded with different golang.org/x/tools/go/packages.Load calls #64477

Closed
jmattheis opened this issue Nov 30, 2023 · 2 comments

Comments

@jmattheis
Copy link

jmattheis commented Nov 30, 2023

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.

@adonovan
Copy link
Member

This is working as intended, according to the design of go/types, though I am sympathetic to the difficulties it causes and we have talked about changing it. It would be more flexible if any pair of Types could be compared, and if the packages of any named types within them were considered equal if they have the same Package.Path string; see #57497.

We could also improve the documentation; see #53914.

@jmattheis
Copy link
Author

Okay, thanks! I'll close this as it's covered in the tickets you've listed.

@jmattheis jmattheis closed this as not planned Won't fix, can't repro, duplicate, stale Nov 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants