Fix panic in add_pending_forbid_clauses during conflict detection#231
Conversation
|
I am not certain about this one - it was mentioned here prefix-dev/resolvo-rpm#2 (comment) that
So it would make sense that backtracking w/ soft requirements would be needed, but I'm not sure if this is a complete fix. IDK if something more needs to happen with soft requirements or maybe with how |
|
Here's the full description from claude which has a little bit more detail.
It's possible my implementation of |
|
Also, a question: While I haven't gotten around to needing to deal with this part yet, I know that DNF can whitelist certain packages to have multiple versions installed in parallel - e.g. multiple different versions of the kernel package (for emergency boot into an older kernel) I presume then that this codepath would need to be turned off in that case? Is there an equivalent to libsolv's |
baszalmstra
left a comment
There was a problem hiding this comment.
Do you think you can add a regression test for this case?
The fix look good to me.
I wonder how this is implemented in libsolv. I can also imagine that you can implement this using a "virtual name" maybe? But I would have to dive into libsolv to see how this works. Would be a very interesting case to support! |
|
@baszalmstra regression test added - I verified that it fails w/o the patch present. |
Forbid-multiple clauses (which enforce "at most one version of a package") are created lazily as solvables become reachable. When run_sat() decides a solvable true and then encodes its dependencies, add_pending_forbid_clauses may discover that another solvable for the same package name was already decided true — but the forbid clause between them didn't exist yet to prevent it. The old code hit unreachable!() in this case. Handle it as a normal conflict instead, so the solver can backtrack and try alternatives. This is triggered by soft_requirements: the hard solve installs version A, then run_sat for a soft requirement decides version B true. During encoding of B, the forbid clause between A and B is finally created, at which point both are already true. Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
…ments Test that the solver correctly handles the case where a soft requirement conflicts with the hard solution when forbid clauses are created lazily, rather than producing an internal error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Perfect thanks! |
Forbid-multiple clauses (which enforce "at most one version of a package") are created lazily as solvables become reachable. When run_sat() decides a solvable true and then encodes its dependencies, add_pending_forbid_clauses may discover that another solvable for the same package name was already decided true — but the forbid clause between them didn't exist yet to prevent it.
The old code hit unreachable!() in this case. Handle it as a normal conflict instead, so the solver can backtrack and try alternatives.
This is triggered by soft_requirements: the hard solve installs version A, then run_sat for a soft requirement decides version B true. During encoding of B, the forbid clause between A and B is finally created, at which point both are already true.
Assisted-By: Claude Opus 4.6 noreply@anthropic.com