|
6 | 6 | use std::fmt::{Debug, Display};
|
7 | 7 | use std::hash::BuildHasherDefault;
|
8 | 8 |
|
| 9 | +use log::debug; |
9 | 10 | use priority_queue::PriorityQueue;
|
10 | 11 | use rustc_hash::FxHasher;
|
11 | 12 |
|
@@ -377,12 +378,37 @@ impl<DP: DependencyProvider> PartialSolution<DP> {
|
377 | 378 | self.has_ever_backtracked = true;
|
378 | 379 | }
|
379 | 380 |
|
380 |
| - /// We can add the version to the partial solution as a decision |
381 |
| - /// if it doesn't produce any conflict with the new incompatibilities. |
382 |
| - /// In practice I think it can only produce a conflict if one of the dependencies |
383 |
| - /// (which are used to make the new incompatibilities) |
384 |
| - /// is already in the partial solution with an incompatible version. |
385 |
| - pub(crate) fn add_package_version_incompatibilities( |
| 381 | + /// Backtrack the partial solution before a particular package was selected. |
| 382 | + /// |
| 383 | + /// This can be used to switch the order of packages if the previous prioritization was bad. |
| 384 | + /// |
| 385 | + /// Returns the new decision level on success and an error if the package was not decided on |
| 386 | + /// yet. |
| 387 | + pub(crate) fn backtrack_package(&mut self, package: Id<DP::P>) -> Result<DecisionLevel, ()> { |
| 388 | + let Some(decision_level) = self.package_assignments.get_index_of(&package) else { |
| 389 | + return Err(()); |
| 390 | + }; |
| 391 | + let decision_level = DecisionLevel(decision_level as u32); |
| 392 | + if decision_level > self.current_decision_level { |
| 393 | + return Err(()); |
| 394 | + } |
| 395 | + debug!( |
| 396 | + "Package backtracking ot decision level {}", |
| 397 | + decision_level.0 |
| 398 | + ); |
| 399 | + self.backtrack(decision_level); |
| 400 | + Ok(decision_level) |
| 401 | + } |
| 402 | + |
| 403 | + /// Add a package version as decision if none of its dependencies conflicts with the partial |
| 404 | + /// solution. |
| 405 | + /// |
| 406 | + /// If the resolution never backtracked before, a fast path adds the package version directly |
| 407 | + /// without checking dependencies. |
| 408 | + /// |
| 409 | + /// Returns the incompatibility that caused the current version to be rejected, if a conflict |
| 410 | + /// in the dependencies was found. |
| 411 | + pub(crate) fn add_package_version_dependencies( |
386 | 412 | &mut self,
|
387 | 413 | package: Id<DP::P>,
|
388 | 414 | version: DP::V,
|
|
0 commit comments