From aa7d2f55a0b0d683fbcd46d2a80c99957b788c3a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 25 Apr 2020 10:00:34 +0200 Subject: Discard impossible candidate versions also for non-installed We reseted the candidate for installed packages back to the version which is installed if one of the (critical) dependencies of it is not statisfiable, but we can do the same for non-installed packages by discarding the candidate which beside slightly helping the resolver also improves error messages generated by apt as a sideeffect. --- apt-pkg/depcache.cc | 47 ++++++++++------------ .../test-bug-735967-lib32-to-i386-unavailable | 2 +- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 052e3de0e..d43c1522e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1399,45 +1399,40 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con for (DepIterator Dep = CandVer.DependsList(); Dep.end() != true;) { - // Grok or groups DepIterator Start = Dep; - bool Result = true; + bool foundSolution = false; unsigned Ors = 0; - for (bool LastOR = true; Dep.end() == false && LastOR == true; ++Dep, ++Ors) + // Is it possible to statisfy this dependency? + for (bool LastOR = true; not Dep.end() && LastOR; ++Dep, ++Ors) { LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or; - if ((DepState[Dep->ID] & DepInstall) == DepInstall) - Result = false; + if ((DepState[Dep->ID] & (DepInstall | DepCVer)) != 0) + foundSolution = true; } - if (Start.IsCritical() == false || Start.IsNegative() == true || Result == false) + if (foundSolution || not Start.IsCritical() || Start.IsNegative()) continue; - /* If we are in an or group locate the first or that can succeed. - We have already cached this… */ - for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; --Ors) - ++Start; + if (DebugAutoInstall == true) + std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl; - if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer) + // the dependency is critical, but can't be installed, so discard the candidate + // as the problemresolver will trip over it otherwise trying to install it (#735967) + StateCache &State = PkgState[Pkg->ID]; + if (not State.Protect()) { - if (DebugAutoInstall == true) - std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl; - - // the dependency is critical, but can't be installed, so discard the candidate - // as the problemresolver will trip over it otherwise trying to install it (#735967) - if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected) - { + if (Pkg->CurrentVer != 0) SetCandidateVersion(Pkg.CurrentVer()); - StateCache &State = PkgState[Pkg->ID]; - if (State.Mode != ModeDelete) - { - State.Mode = ModeKeep; - State.Update(Pkg, *this); - } - } - return false; + else + State.CandidateVer = nullptr; + if (not State.Delete()) + { + State.Mode = ModeKeep; + State.Update(Pkg, *this); + } } + return false; } return true; diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable index 3b705d5f9..16aee4340 100755 --- a/test/integration/test-bug-735967-lib32-to-i386-unavailable +++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable @@ -52,7 +52,7 @@ or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: - foo : Depends: libfoo but it is not going to be installed + foo : Depends: libfoo but it is not installable E: Unable to correct problems, you have held broken packages.' aptget install foo -s # activate multiarch -- cgit v1.2.3-70-g09d2