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: doc: clarify that Named types are canonical only within one Importer #66690

Closed
xieyuschen opened this issue Apr 5, 2024 · 5 comments
Assignees
Labels
Documentation NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@xieyuschen
Copy link

Go version

go version go1.21.3 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/yuchen.xie/Library/Caches/go-build'
GOENV='/Users/yuchen.xie/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/yuchen.xie/go/pkg/mod'
GONOPROXY='git.garena.com'
GONOSUMDB='git.garena.com'
GOOS='darwin'
GOPATH='/Users/yuchen.xie/go'
GOPRIVATE='git.garena.com'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.2'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/yuchen.xie/workspace/verify-identical/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 -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/28/7sypdf0519xfl4ylhq_90s0m0000gp/T/go-build3792409280=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I used SSA to load the packages and tried to compare the types using types.Identical, but if the packages are loaded separately, the types.Identical won't return the correct result.

I have written my use cases here: https://github.com/xieyuschen/verify-identical/blob/master/main_test.go.

Its pipeline shows the result: https://github.com/xieyuschen/verify-identical/actions/runs/8564767599/job/23471810349

--- FAIL: TestFailCase (1.23s)
    --- FAIL: TestFailCase/Mutex_is_not_identical_when_load_sync_twice (0.67s)
        main_test.go:39: actual and expected type are different
    --- FAIL: TestFailCase/Mutex_is_not_identical_between_loading_from_sync_and_retrieving_from_code (0.30s)
        main_test.go:39: actual and expected type are different
FAIL
FAIL	github.com/xieyuschen/verify-identical	1.237s

What did you see happen?

Unexpected Cases

  • load the sync package and get the Mutex type twice, and then check whether they are identical. The result is they're not identical.
  • load the sync package and another package which has a variable with type sync.Mutex, and then check whether they are identical. The result is they're not identical.

Successful Case

If I load the package only once, and then get the variable with sync.Mutex type from the user-package and the Mutex type from sync package, their types are identical.

What did you expect to see?

I want to see that no matter how the packages are loaded and types are retrieved, as long as they're identical(for example, they comes from the same revision of the same code, the types.Identical should return true. Sorry for the possible un-precise description of the identical due to my limited knowledge about type system. The possible of this idea is that what if users change their dependencies on the fly as the SSA will help you to resolve the dependencies.

The current implementation compares the pointer directly in the identicalOrigin, which will of course fail the cases I mentioned because loading multiple times produce different pointers. It hits the concern left by @griesemer .

I tried a simple change in the identicalOrigin in my fork: xieyuschen@78b6c82, but it's not really helpful because even the obj fields contain different values. I believe this is caused by the pointers hold inside the obj structure.

Due to this, I stoped my investigation as I feel like it's very likely something that closely embedded inside the compiler and a great of complexities are hidden. I am not sure:

  • whether the behavior is expected or not. but I do haven't found documents about it.
  • whether it's an SSA issue instead of the go/types package

If it's worthy fixing, i would like to spend more time about the details. If not, i'd like to add a comment for both types and SSA to state more details about this.

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. FixPending Issues that have a fix which has not yet been reviewed or submitted. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. and removed NeedsFix The path to resolution is known, but the work has not been done. FixPending Issues that have a fix which has not yet been reviewed or submitted. labels Apr 5, 2024
@dmitshur dmitshur added this to the Backlog milestone Apr 5, 2024
@dmitshur
Copy link
Contributor

dmitshur commented Apr 5, 2024

CC @griesemer, @findleyr.

@findleyr
Copy link
Contributor

findleyr commented Apr 5, 2024

This is expected behavior. Two (non-generic) Named types are only identical if they were produced during the same type-checking pass.

See #57497 for a proposal to change this behavior, which is similar to what you request. It would be a very large change, but is perhaps doable and would be useful in a number of scenarios.

CC @adonovan

@adonovan
Copy link
Member

adonovan commented Apr 5, 2024

I was going to close this as "working as intended", but perhaps there's a doc change that could highlight the risk. I've retitled the issue. Although it says go/types, corresponding changes may be wanted in packages.Load and ssautil.BuildPackages.

@adonovan adonovan changed the title go/types: Identical function doesn't work for SSA loaded type go/types: doc: clarify that Named types are canonical only within one Importer Apr 5, 2024
@adonovan adonovan self-assigned this Apr 5, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/577015 mentions this issue: go/types: Identical: document the need for consistent symbol realms

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/577256 mentions this issue: go/packages: doc: type symbols are consistent only within one Load

gopherbot pushed a commit to golang/tools that referenced this issue Apr 8, 2024
Updates golang/go#66690

Change-Id: I26199c39434ab83c1a25756bd5f135a0ea785fad
Reviewed-on: https://go-review.googlesource.com/c/tools/+/577256
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
@dmitshur dmitshur modified the milestones: Backlog, Go1.23 Apr 8, 2024
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants