Skip to content

Conversation

@slavapestov
Copy link
Contributor

6.3 cherry-pick of #86352.

  • Description: Fix accidental modification of a DenseMap inside the selectDisjunction() algorithm. The accesses of the values from the DenseMap were unintentionally declared as references, when they should be values, because the assignments were not meant to be written back to the DenseMap.

  • Origination: The new logic was part of the solver-perf optimizations and did not ship in a release yet.

  • Tested: I do not have a test case to exercise the formerly-incorrect behavior. I only found the problem while debugging some changes to the algorithm where I intentionally performed the selection pass twice, and I noticed the result was not deterministic.

  • Risk: Disjunction selection order can affect both performance, and -- unfortunately -- the actual solution produced by the solver. There is some remote risk this incorrect behavior was load-bearing in some cases, but this is why I want to land it in 6.3, since we don't want users to rely on it going forward.

  • Reviewed by: @xedin

…Disjunction()

The firstScore and secondScore bindings were references, so the
assignments to those were mutating the DenseMap unintentionally.

Refactor this code a bit, we don't want to just change the
bindings to rvalues because then we would copy the FavoredChoices
vector, so instead bind a const reference to the DisjunctionInfo
and dereference its fields instead.
@slavapestov slavapestov requested a review from a team as a code owner January 8, 2026 14:39
@slavapestov
Copy link
Contributor Author

@swift-ci Please test

if (firstActive == 1 || secondActive == 1)
return secondActive != 1;

if (auto preference = isPreferable(*this, first, second))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slavapestov out of curiosity: i thought there was some frontend/driver setting to try and catch nondeterminism that would like compile twice and compare the outputs – would that have caught this? (assuming i'm not hallucinating...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the non-determinism here can only be caught by invoking the predicate more than once on the same pair of inputs and observing that it produces a different result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it’s more accurate to say the predicate had an unexpected side effect which changed subsequent calls, instead of being non-deterministic. The overall compiler invocation is still deterministic in its output.

@slavapestov slavapestov merged commit 7951d41 into swiftlang:release/6.3 Jan 9, 2026
5 checks passed
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

Successfully merging this pull request may close these issues.

4 participants