.get(&dep)
.and_then(|past_bad| {
past_bad.iter().find(|conflicting| {
- conflicting
- .iter()
- // note: a lot of redundant work in is_active for similar debs
- .all(|(con, _)| cx.is_active(con))
+ cx.is_conflicting(None, conflicting)
})
})
.is_some();
// but we may want to scrap it if it is not going to end well
let mut has_past_conflicting_dep = just_here_for_the_error_messages;
if !has_past_conflicting_dep {
- if let Some(conflicting) = frame
- .remaining_siblings
- .clone()
- .filter_map(|(_, (deb, _, _))| {
- past_conflicting_activations.get(&deb).and_then(|past_bad| {
- // for each dependency check all of its cashed conflicts
- past_bad.iter().find(|conflicting| {
- conflicting
- .iter()
- // note: a lot of redundant work in is_active for similar debs
- .all(|(con, _)| cx.is_active(con))
- })
+ if let Some(conflicting) = frame.remaining_siblings.clone().filter_map(|(_, (deb, _, _))| {
+ past_conflicting_activations.get(&deb).and_then(|past_bad| {
+ // for each dependency check all of its cashed conflicts
+ past_bad.iter().find(|conflicting| {
+ cx.is_conflicting(None, conflicting)
})
})
- .next()
+ }).next()
{
// if any of them match than it will just backtrack to us
// so let's save the effort.
conflicting_activations
);
past.push(conflicting_activations.clone());
+ // also clean the `backtrack_stack` so we don't
+ // backtrack to a place where we will try this again.
+ backtrack_stack.retain(|bframe| !bframe.context_backup.is_conflicting(Some(parent.package_id()), &conflicting_activations));
}
}
// if not has_another we we activate for the better error messages
conflicting_activations: &HashMap<PackageId, ConflictReason>,
) -> Option<(Candidate, bool, BacktrackFrame)> {
while let Some(mut frame) = backtrack_stack.pop() {
- let next = frame.remaining_candidates.next(
- frame.context_backup.prev_active(&frame.dep),
- &frame.context_backup.links,
- );
- if frame.context_backup.is_active(parent.package_id())
- && conflicting_activations
- .iter()
- // note: a lot of redundant work in is_active for similar debs
- .all(|(con, _)| frame.context_backup.is_active(con))
+ let next= frame.remaining_candidates.next(frame.context_backup.prev_active(&frame.dep), &frame.context_backup.links,);
+ if frame.context_backup.is_conflicting(Some(parent.package_id())
+ , conflicting_activations
+ )
{
continue;
}
.unwrap_or(false)
}
+ /// checks whether all of `parent` and the keys of `conflicting activations`
+ /// are still active
+ fn is_conflicting(
+ &self,
+ parent: Option<&PackageId>,
+ conflicting_activations: &HashMap<PackageId, ConflictReason>,
+ ) -> bool {
+ parent.map(|p| self.is_active(p)).unwrap_or(true) &&
+ conflicting_activations
+ .keys()
+ // note: a lot of redundant work in is_active for similar debs
+ .all(|con| self.is_active(con))
+ }
+
/// Return all dependencies and the features we want from them.
fn resolve_features<'b>(
&mut self,