-
Notifications
You must be signed in to change notification settings - Fork 18k
sync: Map - reflect.DeepEqual regression between Go 1.23 and 1.24 #71702
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
Comments
There's a new sync.Map implementation controllable via GOEXPERIMENT value. In the test use cases, we likely don't care about the strict reflect equality so we can swap to an alternative comparison implementation. Other uses of reflect.DeepEqual(...) at runtime don't appear to operate over sync.Map instances and so aren't affected. See also: https://tip.golang.org/doc/go1.24#syncpkgsync See also: golang/go#71702 Signed-off-by: Alexander Scheel <ascheel@gitlab.com>
Related Issues
Related Code Changes (Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
There's a new sync.Map implementation controllable via GOEXPERIMENT value. In the test use cases, we likely don't care about the strict reflect equality so we can swap to an alternative comparison implementation. Other uses of reflect.DeepEqual(...) at runtime don't appear to operate over sync.Map instances and so aren't affected. See also: https://tip.golang.org/doc/go1.24#syncpkgsync See also: golang/go#71702 Signed-off-by: Alexander Scheel <ascheel@gitlab.com>
The internal representations of any struct aren't subject to stability guarantees. |
@seankhliao While I concur, note that this leaks via GitHub presently shows ~170k usages for The Go docs merely note: https://pkg.go.dev/reflect#DeepEqual
But nothing about behavior changes across versions. It seems like there'd be value in making My usage is all in tests, so I'm happy to keep closed if that's the consensus. |
Go carves out the addition of struct fields, these may or may not be compared equal with DeepEqual, regardless if it's exported or an internal detail. |
I see. Thank you for the clarification. Should #43993 be extended to forbid all use of reflect.DeepEqual on standard library objects? |
* Update to Go 1.24.0 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix reflect comparisons due to sync.Map changes There's a new sync.Map implementation controllable via GOEXPERIMENT value. In the test use cases, we likely don't care about the strict reflect equality so we can swap to an alternative comparison implementation. Other uses of reflect.DeepEqual(...) at runtime don't appear to operate over sync.Map instances and so aren't affected. See also: https://tip.golang.org/doc/go1.24#syncpkgsync See also: golang/go#71702 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix certificate parsing, issuing bugs Go now forbids creating 512-bit RSA keys and uses x509.Certificate.Policies as the field for policy identifiers. See also: https://go.dev/doc/go1.24#cryptorsapkgcryptorsa See also: https://go.dev/doc/go1.24#cryptox509pkgcryptox509 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix additional uses of formatters with constants Signed-off-by: Alexander Scheel <ascheel@gitlab.com> --------- Signed-off-by: Alexander Scheel <ascheel@gitlab.com>
I filed #71732 for one take on this. |
* Update to Go 1.24.0 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix reflect comparisons due to sync.Map changes There's a new sync.Map implementation controllable via GOEXPERIMENT value. In the test use cases, we likely don't care about the strict reflect equality so we can swap to an alternative comparison implementation. Other uses of reflect.DeepEqual(...) at runtime don't appear to operate over sync.Map instances and so aren't affected. See also: https://tip.golang.org/doc/go1.24#syncpkgsync See also: golang/go#71702 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix certificate parsing, issuing bugs Go now forbids creating 512-bit RSA keys and uses x509.Certificate.Policies as the field for policy identifiers. See also: https://go.dev/doc/go1.24#cryptorsapkgcryptorsa See also: https://go.dev/doc/go1.24#cryptox509pkgcryptox509 Signed-off-by: Alexander Scheel <ascheel@gitlab.com> * Fix additional uses of formatters with constants Signed-off-by: Alexander Scheel <ascheel@gitlab.com> --------- Signed-off-by: Alexander Scheel <ascheel@gitlab.com>
Go version
go version go1.24.0 linux/amd64
Output of
go env
in your module/workspace:What did you do?
Go 1.24: https://go.dev/play/p/Dsu_70d--CL
Go 1.23: https://go.dev/play/p/Dsu_70d--CL?v=goprev
What did you see happen?
Calling
sync.Map.Delete(...)
on two empty maps results in afalse
value fromreflect.DeepEqual
when comparing those maps.Before delete, this is memory is:
Post delete:
Note that
seed
is now initialized.What did you expect to see?
On Go 1.23, this previously was
true
, i.e., the maps were equal, due to the simpler implementation.In particular,
reflect
appears to be recursing into the internalHashTrieMap
implementation from the experiment now, with seed differing post-Delete.We can work around this by using an alternative
DeepEqual
implementation in the test suite, but it is still an unfortunate issue.The text was updated successfully, but these errors were encountered: