-
Notifications
You must be signed in to change notification settings - Fork 469
Fix apparent nondeterminism in pattern matching compilation. #7557
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 #7465 Pattern matching compilation has some code to find if some exit is used at least 3 times. This is done by iterating on a hash table. However, the exit id is generated based on a global counter, which determines which exit value `n` is generated. This can affect the order in which the hash table is traversed, as the exit id is hashed. This PR makes the code generation deterministic by adding a tie-breaker if more than id leads to the same exit being used at least 3 times: take the smaller id.
2fddf8e
to
c2a29d0
Compare
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/win32-x64
commit: |
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.
Amazing!
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.
Pull Request Overview
This PR fixes an issue with nondeterministic behavior in pattern matching compilation by introducing a deterministic tie-breaker in exit id selection. Key changes include updated tests in JavaScript and ReScript for pattern matching, a revised tie-breaker condition in the compiler backend, and a changelog entry documenting the fix.
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
tests/tests/src/adt_optimize_test.mjs | Updated test cases to reflect changes in pattern matching behavior. |
tests/tests/src/NondetPatterMatch.res | Added new tests with ReScript syntax for pattern matching. |
tests/tests/src/NondetPatterMatch.mjs | Added new tests with JS patterns for validating pattern matching. |
compiler/ml/matching.ml | Updated tie-breaker logic for exit id selection to improve determinism. |
CHANGELOG.md | Documented the fix in the changelog. |
@@ -1808,7 +1808,10 @@ let reintroduce_fail sw = | |||
let i_max = ref (-1) and max = ref (-1) in | |||
Hashtbl.iter | |||
(fun i c -> | |||
if c > !max then ( | |||
if | |||
c > !max || (c = !max && i > !i_max) |
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.
The tie-break condition claims to choose the smallest index, but the condition 'i > !i_max' actually selects the larger index. Consider revising it to 'i < !i_max' to ensure the intended deterministic behavior.
c > !max || (c = !max && i > !i_max) | |
c > !max || (c = !max && i < !i_max) |
Copilot uses AI. Check for mistakes.
Fixes #7465
Pattern matching compilation has some code to find if some exit is used at least 3 times. This is done by iterating on a hash table. However, the exit id is generated based on a global counter, which determines which exit value
n
is generated. This can affect the order in which the hash table is traversed, as the exit id is hashed. This PR makes the code generation deterministic by adding a tie-breaker if more than id leads to the same exit being used at least 3 times: take the smaller id.