-
Notifications
You must be signed in to change notification settings - Fork 786
Fix isorecursive canonicalization #5269
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
Conversation
Fixes a longstanding problem with isorecursive canonicalization that only showed up in MacOS and occasionally Windows builds. The problem was that `RecGroupEquator` was not quite correct in the presence of self-references in rec groups. Specifically, `RecGroupEquator` did not differentiate between instances of the same type appearing across two rec groups where the type was a self-reference in one group but not in the other. The reason this only showed up occasionally on some platforms was that this bug could only cause incorrect behavior if two groups that would incorrectly be compared as equal were hashed into the same bucket of a hash map. Apparently the hash map used on Linux never hashes the two problematic groups into the same bucket.
Current dependencies on/for this PR:
This comment was auto-generated by Graphite. |
return groupA == groupB || (groupA == newGroup && groupB == otherGroup); | ||
bool selfRefA = groupA == newGroup; | ||
bool selfRefB = groupB == otherGroup; | ||
return (selfRefA && selfRefB) || (!selfRefA && !selfRefB && groupA == groupB); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've forgotten how this code works, sorry. Is newGroup
a new group being built that is being compared to an existing group otherGroup
? How can groupA/B
not match those two, why would we be comparing types not from the groups at all, when comparing newGroup/otherGroup
?
I couldn't find code comments explaining how the class RecGroupEquator
is used - are they somewhere else than on the class itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've forgotten how this code works, sorry. Is newGroup a new group being built that is being compared to an existing group otherGroup?
Yes, exactly.
How can
groupA/B
not match those two, why would we be comparing types not from the groups at all, when comparingnewGroup/otherGroup
?
Because we might be comparing heap types that are used in newGroup
and otherGroup
(e.g. because structs defined in those groups contain reference to the heap types), but are defined in some arbitrary different previous groups. We're trying to compare the "shapes" of newGroup
and otherGroup
, and how they reference other groups is part of that "shape."
I couldn't find code comments explaining how the class RecGroupEquator is used - are they somewhere else than on the class itself?
There are some additional comments on RecGroupStructure
and RecGroupStore
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm (I assume my remaining question is a small misunderstanding on my part)
Can we add a test for this?
This would be difficult since |
sgtm, a re-enabled flaky test that is now stable seems enough. |
Fixes a longstanding problem with isorecursive canonicalization that only showed
up in MacOS and occasionally Windows builds. The problem was that
RecGroupEquator
was not quite correct in the presence of self-references inrec groups. Specifically,
RecGroupEquator
did not differentiate betweeninstances of the same type appearing across two rec groups where the type was a
self-reference in one group but not in the other.
The reason this only showed up occasionally on some platforms was that this bug
could only cause incorrect behavior if two groups that would incorrectly be
compared as equal were hashed into the same bucket of a hash map. Apparently the
hash map used on Linux never hashes the two problematic groups into the same
bucket.