Skip to content

Commit 58d7cf1

Browse files
committed
more comments
1 parent 290a210 commit 58d7cf1

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/cargo/core/resolver/mod.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,17 @@ fn activate_deps_loop(
788788
// use (those with more candidates).
789789
let mut backtrack_stack = Vec::new();
790790
let mut remaining_deps = BinaryHeap::new();
791+
// `past_conflicting_activations`is a cache of the reasons for each time we backtrack.
792+
// for example after several backtracks we may have:
793+
// past_conflicting_activations[`foo = "^1.0.2"`] = vac![map!{`foo=1.0.1`: Semver}, map!{`foo=1.0.1`: Semver}];
794+
// This can be read as "we cannot find a candidate for dep `foo = "^1.0.2"` if either
795+
// `foo=1.0.1` OR `foo=1.0.0` are activated"
796+
// for another example after several backtracks we may have:
797+
// past_conflicting_activations[`foo = ">=0.8.2, <=0.9.3"`] = vac![map!{`foo=0.8.1`: Semver, `foo=0.9.4`: Semver}];
798+
// This can be read as "we cannot find a candidate for dep `foo = ">=0.8.2, <=0.9.3"` if both
799+
// `foo=0.8.1` AND `foo=0.9.4` are activated" (better data structures are welcome but this works for now.)
800+
// This is used to make sure we don't queue work we know will fail.
801+
// See the discussion in https://github.com/rust-lang/cargo/pull/5168 for why this is so important
791802
let mut past_conflicting_activations: HashMap<Dependency, Vec<HashMap<PackageId, ConflictReason>>> = HashMap::new();
792803
for &(ref summary, ref method) in summaries {
793804
debug!("initial activation: {}", summary.package_id());
@@ -874,8 +885,15 @@ fn activate_deps_loop(
874885

875886
let mut remaining_candidates = RemainingCandidates::new(&candidates);
876887
let mut successfully_activated = false;
877-
let mut backtracked = false;
888+
// `conflicting_activations` stores all the reasons we were unable to activate candidates.
889+
// One of these reasons will have to go away for backtracking to find a place to restart.
890+
// It is also the list of things to explain in the error message if we fail to resolve.
878891
let mut conflicting_activations = HashMap::new();
892+
// When backtracking we don't fully update `conflicting_activations` especially for the
893+
// cases that we didn't make a backtrack frame in the first place.
894+
// This `backtracked` var stores whether we are continuing from a restored backtrack frame
895+
// so that we can skip caching `conflicting_activations` in `past_conflicting_activations`
896+
let mut backtracked = false;
879897

880898
while !successfully_activated {
881899
let next = remaining_candidates.next(cx.prev_active(&dep), &cx.links);
@@ -900,6 +918,8 @@ fn activate_deps_loop(
900918
trace!("{}[{}]>{} -- no candidates", parent.name(), cur, dep.name());
901919

902920
if !just_here_for_the_error_messages && !backtracked {
921+
// if `just_here_for_the_error_messages` then skip as it is already known to be bad.
922+
// if `backtracked` then `conflicting_activations` may not be complete so skip.
903923
let past = past_conflicting_activations.entry(dep.clone()).or_insert_with(Vec::new);
904924
if !past.contains(&conflicting_activations) {
905925
trace!("{}[{}]>{} adding a skip {:?}", parent.name(), cur, dep.name(), conflicting_activations);
@@ -972,25 +992,31 @@ fn activate_deps_loop(
972992

973993
match res {
974994
Ok(Some((mut frame, dur))) => {
995+
// at this point we have technical already activated
996+
// but we may want to scrap it if it is not going to end well
975997
let mut has_past_conflicting_dep = just_here_for_the_error_messages;
976998
if !has_past_conflicting_dep {
977999
if let Some(conflicting) = frame.remaining_siblings.clone().filter_map(|(_, (deb, _, _))| {
9781000
past_conflicting_activations.get(&deb).and_then(|past_bad| {
1001+
// for each dependency check all of its cashed conflicts
9791002
past_bad.iter().find(|conflicting| {
9801003
conflicting
9811004
.iter()
9821005
// note: a lot of redundant work in is_active for similar debs
983-
.all(|(con, _)| cx.is_active(con) || *con == pid)
1006+
.all(|(con, _)| cx.is_active(con))
9841007
})
9851008
})
9861009
}).next() {
1010+
// if any of them match than it will just backtrack to us
1011+
// so let's save the effort.
9871012
conflicting_activations.extend(conflicting.clone());
9881013
has_past_conflicting_dep = true;
9891014
}
9901015
}
9911016
if !has_another && has_past_conflicting_dep && !backtracked {
9921017
// we have not activated ANY candidates and
993-
// we are out of choices
1018+
// we are out of choices so add it to the cache
1019+
// so our parent will know that we don't work
9941020
let past = past_conflicting_activations.entry(dep.clone()).or_insert_with(Vec::new);
9951021
if !past.contains(&conflicting_activations) {
9961022
trace!("{}[{}]>{} adding a meta-skip {:?}", parent.name(), cur, dep.name(), conflicting_activations);

0 commit comments

Comments
 (0)